<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
<title>
ka-Map Overview
</title>
<link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script>
function asd() {
	
		parent.document.title="kaMap.js Overview";
	
}
</script>
</head>
<body bgcolor="white" onload="asd();">

<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> 	<font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top">
<em>
<b>ka-Map</b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<center>
	
	   <h2>kaMap.js</h2>
	
</center>

	


<h4>Summary</h4>
<p>
	
		No overview generated for 'kaMap.js'<BR/><BR/>
	
</p>

<hr>


    <table border="1" cellpadding="3" cellspacing="0" width="100%">
    <tr bgcolor="#CCCCFF" class="TableHeadingColor">
    <td colspan=2><font size="+2">
    
        <b>Class Summary</b>
    
    </font></td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="_eventManager.html">_eventManager</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="_layer.html">_layer</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="_map.html">_map</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="_queueManager.html">_queueManager</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="kaMap.html">kaMap</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    </table>
    <hr/> 


<!-- ========== METHOD SUMMARY =========== -->

	<a name="method_summary"><!-- --></a>
	<table border="1" cellpadding="3" cellspacing="0" width="100%">
		<tr bgcolor="#CCCCFF" class="TableHeadingColor">
			<td colspan=2>
				<font size="+2">
					<b>Method Summary</b>
				</font>
			</td>
		</tr>
	
		
		   <tr bgcolor="white" class="TableRowColor">
		      <td align="right" valign="top" width="1%">
			 <font size="-1">
			    <code>static&nbsp;void</code>
			 </font>
		      </td>
		      <td>
			 <code>
			    <b>
			       <a href="GLOBALS.html#!s!_queueManager_execute">_queueManager_execute</a></b>( pos)
			 </code>
			 <br>
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			 
		      </td>
		   </tr>
		
		   <tr bgcolor="white" class="TableRowColor">
		      <td align="right" valign="top" width="1%">
			 <font size="-1">
			    <code>static&nbsp;Object</code>
			 </font>
		      </td>
		      <td>
			 <code>
			    <b>
			       <a href="GLOBALS.html#!s!safeParseInt">safeParseInt</a></b>( val )
			 </code>
			 <br>
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			 special helper function to parse an integer value safely in case
 it is represented in IEEE format (scientific notation).
		      </td>
		   </tr>
		
	
	</table>
    <p>

<!-- ========== END METHOD SUMMARY =========== -->


        <pre class="sourceview"><span class="comment">/**********************************************************************
 *
 * $Id: overview-summary-kaMap.js.html,v 1.1 2006/03/15 15:56:58 pspencer Exp $
 *
 * purpose: core engine for implementing a tiled, continuous pan mapping
 *          engine.
 *
 * author: Paul Spencer (pspencer<span class="attrib">@dmsolutions</span>.ca)
 *
 * The original kaMap code was written by DM Solutions Group.
 * bug fixes contributed by Lorenzo Becchi and Andrea Cappugi
 * max_extents support by Tim Schaub
 *
 * TODO:
 *
 *   - convert to prototype
 *   - code refactoring for simplification/speed
 *   - code refactoring
 *
 **********************************************************************
 *
 * Copyright (c) 2005, DM Solutions Group Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 **********************************************************************/</span>

<span class="comment">/**
 * kaMap! events
 */</span>
var gnLastEventId = 0;
var KAMAP_ERROR = gnLastEventId ++;
var KAMAP_WARNING = gnLastEventId ++;
var KAMAP_NOTICE = gnLastEventId++;
var KAMAP_INITIALIZED = gnLastEventId ++;
var KAMAP_MAP_INITIALIZED = gnLastEventId ++;
var KAMAP_EXTENTS_CHANGED = gnLastEventId ++;
var KAMAP_SCALE_CHANGED = gnLastEventId ++;
var KAMAP_LAYERS_CHANGED = gnLastEventId ++;
var KAMAP_LAYER_STATUS_CHANGED = gnLastEventId ++;
var KAMAP_CONTEXT_MENU = gnLastEventId ++;
var KAMAP_METAEXTENTS_CHANGED = gnLastEventId++;
var KAMAP_MAP_CLICKED = gnLastEventId++;

<span class="comment">/******************************************************************************
 * kaMap main class
 *
 * construct a new kaMap instance.  Pass the id of the div to put the kaMap in
 *
 * this class is the main API for any application.  Only use the functions
 * provided by this API to ensure everything functions correctly
 *
 * szID - string, the id of a div to put the kaMap! into
 *
 *****************************************************************************/</span>
<span class="reserved">function</span> kaMap( szID ) {
    <span class="reserved">this</span>.isCSS = false;
    <span class="reserved">this</span>.isW3C = false;
    <span class="reserved">this</span>.isIE4 = false;
    <span class="reserved">this</span>.isNN4 = false;
    <span class="reserved">this</span>.isIE6CSS = false;

    <span class="reserved">if</span> (document.images) {
        <span class="reserved">this</span>.isCSS = (document.body &amp;&amp; document.body.style) ? true : false;
        <span class="reserved">this</span>.isW3C = (<span class="reserved">this</span>.isCSS &amp;&amp; document.getElementById) ? true : false;
        <span class="reserved">this</span>.isIE4 = (<span class="reserved">this</span>.isCSS &amp;&amp; document.all) ? true : false;
        <span class="reserved">this</span>.isNN4 = (document.layers) ? true : false;
        <span class="reserved">this</span>.isIE6CSS = (document.compatMode &amp;&amp; document.compatMode.indexOf(<span class="literal">"CSS1"</span>) &gt;= 0) ? true : false;
    }

    <span class="reserved">this</span>.domObj = <span class="reserved">this</span>.getRawObject( szID );
    <span class="reserved">this</span>.domObj.style.overflow = <span class="literal">'hidden'</span>;

    <span class="reserved">this</span>.hideLayersOnMove = false;
    <span class="comment">//if true layer not checked are loaded if false aren't loaded</span>
    <span class="reserved">this</span>.loadUnchecked=false;
    <span class="comment">/**
     * initialization states
     * 0 - not initialized
     * 1 - initializing
     * 2 - initialized
     */</span>
    <span class="reserved">this</span>.initializationState = 0;

    <span class="comment">//track mouse down events</span>
    <span class="reserved">this</span>.bMouseDown = false;

    <span class="comment">//track last recorded mouse position</span>
    <span class="reserved">this</span>.lastx = 0;
    <span class="reserved">this</span>.lasty = 0;

    <span class="comment">//keep a reference to the inside layer since we use it a lot</span>
    <span class="reserved">this</span>.theInsideLayer = null;

    <span class="comment">//viewport width and height are used in many calculations</span>
    <span class="reserved">this</span>.viewportWidth = safeParseInt(<span class="reserved">this</span>.domObj.style.width);
    <span class="reserved">this</span>.viewportHeight = safeParseInt(<span class="reserved">this</span>.domObj.style.height);

    <span class="comment">//track amount the inside layer has moved to help in wrapping images</span>
    <span class="reserved">this</span>.xOffset = 0;
    <span class="reserved">this</span>.yOffset = 0;

    <span class="comment">//track current origin offset value</span>
    <span class="reserved">this</span>.xOrigin = 0;
    <span class="reserved">this</span>.yOrigin = 0;

    <span class="comment">//the name of the current map</span>
    <span class="reserved">this</span>.currentMap = <span class="literal">''</span>;

    <span class="comment">//the current width and height in tiles</span>
    <span class="reserved">this</span>.nWide = 0;
    <span class="reserved">this</span>.nHigh = 0;

    <span class="comment">//current top and left are tracked when the map moves</span>
    <span class="comment">//to start the map at some offset, these would be set to</span>
    <span class="comment">//the appropriate pixel value.</span>
    <span class="reserved">this</span>.nCurrentTop = 0; <span class="comment">//null;</span>
    <span class="reserved">this</span>.nCurrentLeft = 0; <span class="comment">//null;</span>

    <span class="comment">//keep a live reference to aPixel to help with caching problems - hish</span>
    <span class="reserved">this</span>.aPixel = new Image(1,1);
    <span class="reserved">this</span>.aPixel.src = <span class="literal">'images/a_pixel.gif'</span>;

    <span class="comment">//error stack for tracking images that have failed to load</span>
    <span class="reserved">this</span>.imgErrors = new Array();

    <span class="comment">//an array of available maps</span>
    <span class="reserved">this</span>.aMaps = new Array();

    <span class="comment">//tile size and buffer size determine how many tiles to create</span>
    <span class="reserved">this</span>.tileWidth = null;
    <span class="reserved">this</span>.tileHeight = null;
    <span class="reserved">this</span>.nBuffer = 1;

    <span class="reserved">this</span>.baseURL = <span class="literal">''</span>;

    <span class="comment">//size of a pixel, geographically - assumed to be square</span>
    <span class="reserved">this</span>.cellSize = null;

    <span class="comment">//image id counter - helps with reloading failed images</span>
    <span class="reserved">this</span>.gImageID = 0;

    <span class="comment">//event manager</span>
    <span class="reserved">this</span>.eventManager = new _eventManager();

    <span class="comment">//slider stuff</span>
    <span class="reserved">this</span>.as=slideid=null;
    <span class="reserved">this</span>.accelerationFactor=1;
    <span class="reserved">this</span>.pixelsPerStep = 30;
    <span class="reserved">this</span>.timePerStep = 25;

    <span class="comment">//this is a convenience to allow redirecting the client code to a server</span>
    <span class="comment">//other than the one that this file was loaded from.  This may not</span>
    <span class="comment">//work depending on security settings, except for loading tiles since</span>
    <span class="comment">//those come directly from a php script instead of an XmlHttpRequest.</span>
    <span class="comment">//</span>
    <span class="comment">//by default, if this is empty, it loads from the same site as the</span>
    <span class="comment">//page loaded from.  If set, it should be a full http:// reference to the</span>
    <span class="comment">//directory in which init.php, tile.php and the other scripts are located.</span>
    <span class="reserved">this</span>.server = <span class="literal">''</span>;

    <span class="comment">//similarly, this is the global initialization script called once per page</span>
    <span class="comment">//load ... the result of this script tell the client what other scripts</span>
    <span class="comment">//are used for the other functions</span>
    <span class="reserved">this</span>.init = <span class="literal">"init.php"</span>;

    <span class="comment">//these are the values that need to be initialized by the init script</span>
    <span class="reserved">this</span>.tileURL = null;

    <span class="reserved">this</span>.aObjects = [];
    <span class="reserved">this</span>.aCanvases = [];
    <span class="reserved">this</span>.layersHidden = false;

    <span class="reserved">this</span>.aTools = [];

    <span class="comment">/* register the known events */</span>
    <span class="reserved">for</span> (var i=0; i&lt;gnLastEventId; i++) {
        <span class="reserved">this</span>.registerEventID( i );
    }
    <span class="reserved">this</span>.createLayers();
};

kaMap.<span class="reserved">prototype</span>.seekLayer = <span class="reserved">function</span>(doc, name) {
    var theObj;
    <span class="reserved">for</span> (var i = 0; i &lt; doc.layers.length; i++) {
        <span class="reserved">if</span> (doc.layers[i].name == name) {
            theObj = doc.layers[i];
            break;
        }
        <span class="comment">// dive into nested layers if necessary</span>
        <span class="reserved">if</span> (doc.layers[i].document.layers.length &gt; 0) {
            theObj = <span class="reserved">this</span>.seekLayer(document.layers[i].document, name);
        }
    }
    <span class="reserved">return</span> theObj;
};

<span class="comment">// Convert object name string or object reference</span>
<span class="comment">// into a valid element object reference</span>
kaMap.<span class="reserved">prototype</span>.getRawObject = <span class="reserved">function</span>(obj) {
    var theObj;
    <span class="reserved">if</span> (typeof obj == <span class="literal">"string"</span>) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.isW3C) {
            theObj = document.getElementById(obj);
        } <span class="reserved">else</span> <span class="reserved">if</span> (<span class="reserved">this</span>.isIE4) {
            theObj = document.all(obj);
        } <span class="reserved">else</span> <span class="reserved">if</span> (<span class="reserved">this</span>.isNN4) {
            theObj = seekLayer(document, obj);
        }
    } <span class="reserved">else</span> {
        <span class="comment">// pass through object reference</span>
        theObj = obj;
    }
    <span class="reserved">return</span> theObj;
};

<span class="comment">// Convert object name string or object reference</span>
<span class="comment">// into a valid style (or NN4 layer) reference</span>
kaMap.<span class="reserved">prototype</span>.getObject = <span class="reserved">function</span>(obj) {
    var theObj = <span class="reserved">this</span>.getRawObject(obj);
    <span class="reserved">if</span> (theObj &amp;&amp; <span class="reserved">this</span>.isCSS) {
        theObj = theObj.style;
    }
    <span class="reserved">return</span> theObj;
};

<span class="comment">// Retrieve the rendered width of an element</span>
kaMap.<span class="reserved">prototype</span>.getObjectWidth = <span class="reserved">function</span>(obj)  {
    var elem = <span class="reserved">this</span>.getRawObject(obj);
    var result = 0;
    <span class="reserved">if</span> (elem.offsetWidth) {
        result = elem.offsetWidth;
    } <span class="reserved">else</span> <span class="reserved">if</span> (elem.clip &amp;&amp; elem.clip.width) {
        result = elem.clip.width;
    } <span class="reserved">else</span> <span class="reserved">if</span> (elem.style &amp;&amp; elem.style.pixelWidth) {
        result = elem.style.pixelWidth;
    }
    <span class="reserved">return</span> parseInt(result);
};

<span class="comment">// Retrieve the rendered height of an element</span>
kaMap.<span class="reserved">prototype</span>.getObjectHeight = <span class="reserved">function</span>(obj)  {
    var elem = <span class="reserved">this</span>.getRawObject(obj);
    var result = 0;
    <span class="reserved">if</span> (elem.offsetHeight) {
        result = elem.offsetHeight;
    } <span class="reserved">else</span> <span class="reserved">if</span> (elem.clip &amp;&amp; elem.clip.height) {
        result = elem.clip.height;
    } <span class="reserved">else</span> <span class="reserved">if</span> (elem.style &amp;&amp; elem.style.pixelHeight) {
        result = elem.style.pixelHeight;
    }
    <span class="reserved">return</span> parseInt(result);
};

<span class="comment">/**
 * kaMap.zoomTo( lon, lat [, scale] )
 *
 * zoom to some geographic point (in current projection) and optionally scale
 *
 * lon - the x coordinate to zoom to
 * lat - the y coordinate to zoom to
 * scale - optional. The scale to use
 */</span>
kaMap.<span class="reserved">prototype</span>.zoomTo = <span class="reserved">function</span>( cgX, cgY ) {
    var oMap = <span class="reserved">this</span>.getCurrentMap();
    var inchesPerUnit = new Array(1, 12, 63360.0, 39.3701, 39370.1, 4374754);
    var newScale;
    var bScaleChanged = false;
    <span class="reserved">if</span> (arguments.length == 3) {
        newScale = arguments[2];
        bScaleChanged = (newScale != <span class="reserved">this</span>.getCurrentScale())
    } <span class="reserved">else</span> {
        newScale = <span class="reserved">this</span>.getCurrentScale();
    }
    <span class="reserved">this</span>.cellSize = newScale/(oMap.resolution * inchesPerUnit[oMap.units]);
    var nFactor = oMap.zoomToScale( newScale );
    <span class="reserved">this</span>.setMapLayers();
    var cpX = cgX / <span class="reserved">this</span>.cellSize;
    var cpY = cgY / <span class="reserved">this</span>.cellSize;

    var vpLeft = Math.round(cpX - <span class="reserved">this</span>.viewportWidth/2);
    var vpTop = Math.round(cpY + <span class="reserved">this</span>.viewportHeight/2);


    <span class="comment">//figure out which tile the center point lies on</span>
    var cTileX = Math.floor(cpX/<span class="reserved">this</span>.tileWidth)*<span class="reserved">this</span>.tileWidth;
    var cTileY = Math.floor(cpY/<span class="reserved">this</span>.tileHeight)*<span class="reserved">this</span>.tileHeight;


    <span class="comment">//figure out how many tiles left and up we need to move to lay out from</span>
    <span class="comment">//the top left and have the top/left image off screen (or partially)</span>
    var nTilesLeft = Math.ceil(<span class="reserved">this</span>.viewportWidth/(2*<span class="reserved">this</span>.tileWidth))*<span class="reserved">this</span>.tileWidth;
    var nTilesUp = Math.ceil(<span class="reserved">this</span>.viewportHeight/(2*<span class="reserved">this</span>.tileHeight))*<span class="reserved">this</span>.tileHeight;

    <span class="reserved">this</span>.nCurrentLeft = cTileX - nTilesLeft;
    <span class="reserved">this</span>.nCurrentTop = -1*(cTileY + nTilesUp);

    <span class="reserved">this</span>.xOrigin = <span class="reserved">this</span>.nCurrentLeft;
    <span class="reserved">this</span>.yOrigin = <span class="reserved">this</span>.nCurrentTop;

    <span class="reserved">this</span>.theInsideLayer.style.left = -1*(vpLeft - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
    <span class="reserved">this</span>.theInsideLayer.style.top = (vpTop + <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;

    var layers = oMap.getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        <span class="reserved">for</span>(var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
            <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
                var img = d.childNodes[(j*<span class="reserved">this</span>.nWide)+i];
                img.src = <span class="reserved">this</span>.aPixel.src;
                img.style.top = (<span class="reserved">this</span>.nCurrentTop + j*<span class="reserved">this</span>.tileHeight - <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
                img.style.left = (<span class="reserved">this</span>.nCurrentLeft + i*<span class="reserved">this</span>.tileWidth - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
                layers[k].setTile(img);
            }
        }
    }
    <span class="reserved">this</span>.checkWrap( );
    <span class="reserved">this</span>.updateObjects();
    <span class="reserved">if</span> (bScaleChanged) <span class="reserved">this</span>.triggerEvent( KAMAP_SCALE_CHANGED, <span class="reserved">this</span>.getCurrentScale() );
    <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
};

<span class="comment">/**
 * kaMap.zoomToExtents( minx, miny, maxx, maxy )
 *
 * best fit zoom to extents.  Center of extents will be in the center of the
 * view and the extents will be contained within the view at the closest scale
 * available above the scale these extents represent
 *
 * minx, miny, maxx, maxy - extents in units of current projection.
 */</span>
kaMap.<span class="reserved">prototype</span>.zoomToExtents = <span class="reserved">function</span>(minx, miny, maxx, maxy) {
    <span class="comment">/* calculate new scale from extents and viewport, then find closest
     * scale and calculate new extents from centerpoint and scale.  Then
     * move theInsideLayer and all the images to show that centerpoint at
     * the center of the view at the given scale
     */</span>
    var inchesPerUnit = new Array(1, 12, 63360.0, 39.3701, 39370.1, 4374754);
    var oMap = <span class="reserved">this</span>.getCurrentMap();

    <span class="comment">//the geographic center - where we want to end up</span>
    var cgX = (maxx+minx)/2;
    var cgY = (maxy+miny)/2;

    var tmpCellSizeX = (maxx - minx)/<span class="reserved">this</span>.viewportWidth;
    var tmpCellSizeY = (maxy - miny)/<span class="reserved">this</span>.viewportHeight;
    var tmpCellSize = Math.max( tmpCellSizeX, tmpCellSizeY );

    var tmpScale = tmpCellSize * oMap.resolution * inchesPerUnit[oMap.units];
    var newScale = oMap.aScales[0];
    <span class="reserved">for</span> (var i=1; i&lt;oMap.aScales.length; i++) {
        <span class="reserved">if</span> (tmpScale &gt;= oMap.aScales[i]) {
            break;
        }
        newScale = oMap.aScales[i];
    }
    <span class="comment">//now newScale has our new scale size</span>
    <span class="reserved">this</span>.cellSize = newScale/(oMap.resolution * inchesPerUnit[oMap.units]);
    var nFactor = oMap.zoomToScale( newScale );
    <span class="reserved">this</span>.setMapLayers();
    var cpX = cgX / <span class="reserved">this</span>.cellSize;
    var cpY = cgY / <span class="reserved">this</span>.cellSize;

    var vpLeft = Math.round(cpX - <span class="reserved">this</span>.viewportWidth/2);
    var vpTop = Math.round(cpY + <span class="reserved">this</span>.viewportHeight/2);


    <span class="comment">//figure out which tile the center point lies on</span>
    var cTileX = Math.floor(cpX/<span class="reserved">this</span>.tileWidth)*<span class="reserved">this</span>.tileWidth;
    var cTileY = Math.floor(cpY/<span class="reserved">this</span>.tileHeight)*<span class="reserved">this</span>.tileHeight;


    <span class="comment">//figure out how many tiles left and up we need to move to lay out from</span>
    <span class="comment">//the top left and have the top/left image off screen (or partially)</span>
    var nTilesLeft = Math.ceil(<span class="reserved">this</span>.viewportWidth/(2*<span class="reserved">this</span>.tileWidth))*<span class="reserved">this</span>.tileWidth;
    var nTilesUp = Math.ceil(<span class="reserved">this</span>.viewportHeight/(2*<span class="reserved">this</span>.tileHeight))*<span class="reserved">this</span>.tileHeight;

    <span class="reserved">this</span>.nCurrentLeft = cTileX - nTilesLeft;
    <span class="reserved">this</span>.nCurrentTop = -1*(cTileY + nTilesUp);

    <span class="reserved">this</span>.xOrigin = <span class="reserved">this</span>.nCurrentLeft;
    <span class="reserved">this</span>.yOrigin = <span class="reserved">this</span>.nCurrentTop;

    <span class="reserved">this</span>.theInsideLayer.style.left = -1*(vpLeft - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
    <span class="reserved">this</span>.theInsideLayer.style.top = (vpTop + <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;

    var layers = oMap.getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        <span class="reserved">for</span>(var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
            <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
                var img = d.childNodes[(j*<span class="reserved">this</span>.nWide)+i];
                img.src = <span class="reserved">this</span>.aPixel.src;
                img.style.top = (<span class="reserved">this</span>.nCurrentTop + j*<span class="reserved">this</span>.tileHeight - <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
                img.style.left = (<span class="reserved">this</span>.nCurrentLeft + i*<span class="reserved">this</span>.tileWidth - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
                layers[k].setTile(img);
            }
        }
    }
    <span class="reserved">this</span>.checkWrap( );
    <span class="reserved">this</span>.updateObjects();
    <span class="reserved">this</span>.triggerEvent( KAMAP_SCALE_CHANGED, <span class="reserved">this</span>.getCurrentScale() );
    <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
};

<span class="comment">/**
 * kaMap.createDrawingCanvas( idx )
 *
 * create a layer on which objects can be drawn (such as point objects)
 *
 * idx - int, the z-index of the layer.  Should be &lt; 100 but above the map
 * layers.
 */</span>
kaMap.<span class="reserved">prototype</span>.createDrawingCanvas = <span class="reserved">function</span>( idx ) {
    var d = document.createElement( <span class="literal">'div'</span> );
    d.style.position = <span class="literal">'absolute'</span>;
    d.style.left = <span class="literal">'0px'</span>;
    d.style.top = <span class="literal">'0px'</span>;
    d.style.width= <span class="literal">'3000px'</span>;
    d.style.height = <span class="literal">'3000px'</span>;
    d.style.zIndex = idx;
    <span class="reserved">this</span>.theInsideLayer.appendChild( d );
    <span class="reserved">this</span>.aCanvases.push( d );
    d.kaMap = <span class="reserved">this</span>;
    <span class="reserved">return</span> d;
};

kaMap.<span class="reserved">prototype</span>.removeDrawingCanvas = <span class="reserved">function</span>( canvas ) {

    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.aCanvases.length;i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aCanvases[i] == canvas) {
            <span class="reserved">this</span>.aCanvases.splice( i, 1 );
        }
    }
    <span class="reserved">this</span>.theInsideLayer.removeChild(canvas);
    canvas.kaMap = null;
    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * kaMap.addObjectGeo( canvas, lon, lat, obj )
 *
 * add an object to a drawing layer and position it at the given geographic
 * position.  This is defined as being in the projection of the map.
 *
 * TODO: possibly add ability to call a reprojection service (xhr request?) to
 * convert lon/lat into the current coordinate system if not lon/lat.
 *
 * canvas - object, the drawing canvas to add this object to
 * x - int, the x position in pixels
 * y - int, the y position in pixels
 * obj - object, the object to add (an img, div etc)
 *
 * returns true
 */</span>
kaMap.<span class="reserved">prototype</span>.addObjectGeo = <span class="reserved">function</span>( canvas, lon, lat, obj ) {
    obj.lon = lon;
    obj.lat = lat;
    var aPix = <span class="reserved">this</span>.geoToPix( lon, lat );
    <span class="reserved">return</span> <span class="reserved">this</span>.addObjectPix( canvas, aPix[0], aPix[1], obj );
};

<span class="comment">/**
 * kaMap.addObjectPix( canvas, x, y, obj )
 *
 * add an object to the map canvas and position it at the given pixel position.
 * The position should not include the xOrigin/yOrigin offsets
 *
 * canvas - object, the canvas to add this object to
 * x - int, the x position in pixels
 * y - int, the y position in pixels
 * obj - object, the object to add (an img, div etc)
 *
 * returns true;
 */</span>
kaMap.<span class="reserved">prototype</span>.addObjectPix = <span class="reserved">function</span>( canvas, x, y, obj ) {
    var xOffset = (obj.xOffset) ? obj.xOffset : 0;
    var yOffset = (obj.yOffset) ? obj.yOffset : 0;
    var top = (y - <span class="reserved">this</span>.yOrigin + yOffset);
    var left = (x - <span class="reserved">this</span>.xOrigin + xOffset);
    obj.style.position = <span class="literal">'absolute'</span>;
    obj.style.top = top + <span class="literal">"px"</span>;
    obj.style.left = left + <span class="literal">"px"</span>;
    obj.canvas = canvas;
    canvas.appendChild( obj );
    <span class="reserved">this</span>.aObjects.push( obj );

    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * kaMap.shiftObject( x, y, obj )
 *
 * move an object by a pixel amount
 *
 * x - int, the number of pixels in the x direction to move the object
 * y - int, the number of pixels in the y direction to move the object
 * obj - object, the object to move
 *
 * returns true
 */</span>
kaMap.<span class="reserved">prototype</span>.shiftObject = <span class="reserved">function</span>( x, y, obj ) {
    var top = safeParseInt(obj.style.top);
    var left = safeParseInt(obj.style.left);

    obj.style.top = (top + y) + <span class="literal">"px"</span>;
    obj.style.left = (left + x) + <span class="literal">"px"</span>;

    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * kaMap.removeObject( obj )
 *
 * removes an object previously added with one of the addObjectXxx calls
 *
 * obj - object, an object that has been previously added, or null to remove
 *       all objects
 *
 * returns true if the object was removed, false otherwise (i.e. if it was
 * never added).
 */</span>
kaMap.<span class="reserved">prototype</span>.removeObject = <span class="reserved">function</span>( obj ) {
    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.aObjects.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aObjects[i] == obj || obj == null) {
            <span class="reserved">if</span> (!obj) {
                obj = <span class="reserved">this</span>.aObjects[i];
            }
            <span class="reserved">if</span> (obj.canvas) {
                obj.canvas.removeChild( obj );
                obj.canvas = null;
            }
            <span class="reserved">this</span>.aObjects.splice(i,1);
            <span class="reserved">return</span> true;
        }
    }
    <span class="reserved">return</span> false;
};

<span class="comment">/**
 * kaMap.centerObject( obj )
 *
 * slides the map to place the object at the center of the map
 *
 * obj - object, an object previously added to the map
 *
 * returns true
 */</span>
kaMap.<span class="reserved">prototype</span>.centerObject = <span class="reserved">function</span>(obj) {
    var vpX = -safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left) + <span class="reserved">this</span>.viewportWidth/2;
    var vpY = -safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top) + <span class="reserved">this</span>.viewportHeight/2;

    var xOffset = (obj.xOffset)?obj.xOffset:0;
    var yOffset = (obj.yOffset)?obj.yOffset:0;

    var dx = safeParseInt(obj.style.left) - xOffset- vpX;
    var dy = safeParseInt(obj.style.top) - yOffset - vpY;

    <span class="reserved">this</span>.slideBy(-dx, -dy);
    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * kaMap.geoToPix( gX, gY )
 *
 * convert geographic coordinates into pixel coordinates.  Note this does not
 * adjust for the current origin offset that is used to adjust the actual
 * pixel location of the tiles and other images
 *
 * gX - float, the x coordinate in geographic units of the active projection
 * gY - float, the y coordinate in geographic units of the active projection
 *
 * returns an array of pixel coordinates with element 0 being the x and element
 * 1 being the y coordinate.
 */</span>
kaMap.<span class="reserved">prototype</span>.geoToPix = <span class="reserved">function</span>( gX, gY ) {
    var pX = gX / <span class="reserved">this</span>.cellSize;
    var pY = -1 * gY / <span class="reserved">this</span>.cellSize;
    <span class="reserved">return</span> [Math.floor(pX), Math.floor(pY)];
};

<span class="comment">/**
 * kaMap.pixToGeo( pX, pY [, bAdjust] )
 *
 * convert pixel coordinates into geographic coordinates.  This can optionally
 * adjust for the pixel offset by passing true as the third argument
 *
 * pX - int, the x coordinate in pixel units
 * pY - int, the y coordinate in pixel units
 *
 * returns an array of geographic coordinates with element 0 being the x
 * and element 1 being the y coordinate.
 */</span>
kaMap.<span class="reserved">prototype</span>.pixToGeo = <span class="reserved">function</span>( pX, pY ) {
    var bAdjust = (arguments.length == 3 &amp;&amp; arguments[2]) ? true : false;

    <span class="reserved">if</span> (bAdjust) {
        pX = pX + <span class="reserved">this</span>.xOrigin;
        pY = pY + <span class="reserved">this</span>.yOrigin;
    }
    var gX = -1 * pX * <span class="reserved">this</span>.cellSize;
    var gY = pY * <span class="reserved">this</span>.cellSize;
    <span class="reserved">return</span> [gX, gY];
};

<span class="comment">/**
 * kaMap.initialize( [szMap] )
 *
 * main initialization of kaMap.  This must be called after page load and
 * should only be called once (i.e. on page load).  It does not perform
 * intialization synchronously.  This means that the function will return
 * before initialization is complete.  To determine when initialization is
 * complete, the calling application must register for the KAMAP_INITIALIZED
 * event.
 *
 * szMap - string, optional, the name of a map to initialize by default.  If
 *         not set, use the default configuration map file.
 *
 * returns true
 */</span>
kaMap.<span class="reserved">prototype</span>.initialize = <span class="reserved">function</span>() {
    <span class="reserved">if</span> (<span class="reserved">this</span>.initializationState == 2) {
        <span class="reserved">this</span>.triggerEvent( KAMAP_ERROR, <span class="literal">'ERROR: ka-Map! is already initialized!'</span> );
        <span class="reserved">return</span> false;
    } <span class="reserved">else</span> <span class="reserved">if</span> (<span class="reserved">this</span>.intializationState == 1) {
        <span class="reserved">this</span>.triggerEvent( KAMAP_WARNING, <span class="literal">'WARNING: ka-Map! is currently initializing ... wait for the KAMAP_INITIALIZED event to be triggered.'</span> );
        <span class="reserved">return</span> false;
    }

    <span class="reserved">this</span>.initializationState = 1;
    <span class="comment">/* call initialization script on the server */</span>
    var szURL = <span class="reserved">this</span>.server+<span class="reserved">this</span>.init;

    var sep = (<span class="reserved">this</span>.init.indexOf(<span class="literal">"?"</span>) == -1) ? <span class="literal">"?"</span> : <span class="literal">"&amp;"</span>;

    <span class="reserved">if</span> (arguments.length &gt; 0 &amp;&amp; arguments[0] != <span class="literal">''</span>) {
        szURL = szURL + sep + <span class="literal">"map="</span>+ arguments[0];
        sep = <span class="literal">"&amp;"</span>;
    }
    <span class="reserved">if</span> (arguments.length &gt; 1 &amp;&amp; arguments[1] != <span class="literal">''</span>) {
        szURL = szURL + sep + <span class="literal">"extents="</span>+ arguments[1];
        sep = <span class="literal">"&amp;"</span>;
    }
    <span class="reserved">if</span> (arguments.length &gt; 2 &amp;&amp; arguments[2] != <span class="literal">''</span>) {
        szURL = szURL + sep + <span class="literal">"centerPoint="</span>+ arguments[2];
        sep = <span class="literal">"&amp;"</span>;
    }
    call(szURL, <span class="reserved">this</span>, <span class="reserved">this</span>.initializeCallback);
    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * hidden function on callback from init.php
 */</span>
kaMap.<span class="reserved">prototype</span>.initializeCallback = <span class="reserved">function</span>( szInit ) {
    <span class="comment">// szInit contains /*init*/ if it worked, or some php error otherwise</span>
    <span class="reserved">if</span> (szInit.substr(0, 1) != <span class="literal">"/"</span>) {
        <span class="reserved">this</span>.triggerEvent( KAMAP_ERROR, <span class="literal">'ERROR: ka-Map! initialization '</span>+
                          <span class="literal">'failed on the server.  Message returned was:\n'</span> +
                          szInit);
        <span class="reserved">return</span> false;
    }

    eval(szInit);

    <span class="reserved">this</span>.triggerEvent( KAMAP_INITIALIZED );

    <span class="reserved">this</span>.initializationState = 2;
};

<span class="comment">/**
 * kaMap.setBackgroundColor( color )
 *
 * call this to set a background color for the inside layer.  This color
 * shows through any transparent areas of the map.  This is primarily
 * intended to be used by the initializeMap callback function to set the
 * background to the background color in the map file.
 *
 * color: string, a valid HTML color string
 *
 * returns true;
 */</span>
kaMap.<span class="reserved">prototype</span>.setBackgroundColor = <span class="reserved">function</span>( color ) {
    <span class="reserved">this</span>.domObj.style.backgroundColor = color;
    <span class="reserved">return</span> true;
};

<span class="comment">/**
 * hidden method of kaMap to initialize all the various layers needed by
 * kaMap to draw and move the map image.
 */</span>
kaMap.<span class="reserved">prototype</span>.createLayers = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.theInsideLayer = document.createElement(<span class="literal">'div'</span>);
    <span class="reserved">this</span>.theInsideLayer.id = <span class="literal">'theInsideLayer'</span>;
    <span class="reserved">this</span>.theInsideLayer.style.position = <span class="literal">'absolute'</span>;
    <span class="reserved">this</span>.theInsideLayer.style.left = <span class="literal">'0px'</span>;
    <span class="reserved">this</span>.theInsideLayer.style.top = <span class="literal">'0px'</span>;
    <span class="reserved">this</span>.theInsideLayer.style.zIndex = <span class="literal">'1'</span>;
    <span class="reserved">this</span>.theInsideLayer.kaMap = <span class="reserved">this</span>;
    <span class="reserved">if</span> (<span class="reserved">this</span>.currentTool) {
        <span class="reserved">this</span>.theInsideLayer.style.cursor = <span class="reserved">this</span>.currentTool.cursor;
    }
    <span class="reserved">this</span>.domObj.appendChild(<span class="reserved">this</span>.theInsideLayer);

    <span class="reserved">this</span>.domObj.kaMap = <span class="reserved">this</span>;
    <span class="reserved">this</span>.theInsideLayer.onmousedown = kaMap_onmousedown;
    <span class="reserved">this</span>.theInsideLayer.onmouseup = kaMap_onmouseup;
    <span class="reserved">this</span>.theInsideLayer.onmousemove = kaMap_onmousemove;
    <span class="reserved">this</span>.theInsideLayer.onmouseover = kaMap_onmouseover;
    <span class="reserved">this</span>.domObj.onmouseout = kaMap_onmouseout;
    <span class="reserved">this</span>.theInsideLayer.onkeypress = kaMap_onkeypress;
    <span class="reserved">this</span>.theInsideLayer.ondblclick = kaMap_ondblclick;
    <span class="reserved">this</span>.theInsideLayer.oncontextmenu = kaMap_oncontextmenu;
    <span class="reserved">this</span>.theInsideLayer.onmousewheel = kaMap_onmousewheel;
    <span class="reserved">if</span> (window.addEventListener &amp;&amp;
        navigator.product &amp;&amp; navigator.product == <span class="literal">"Gecko"</span>) {
        <span class="reserved">this</span>.domObj.addEventListener( <span class="literal">"DOMMouseScroll"</span>, kaMap_onmousewheel, false );
    }

    <span class="comment">//this is to prevent problems in IE</span>
    <span class="reserved">this</span>.theInsideLayer.ondragstart = new Function([], <span class="literal">'var e=e?e:event;e.cancelBubble=true;e.returnValue=false;return false;'</span>);
};

<span class="comment">/**
 * internal function
 * update the layer URLs based on their current positions
 */</span>
kaMap.<span class="reserved">prototype</span>.initializeLayers = <span class="reserved">function</span>(nFactor) {
    var deltaMouseX = <span class="reserved">this</span>.nCurrentLeft + safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left) - <span class="reserved">this</span>.xOrigin;
    var deltaMouseY = <span class="reserved">this</span>.nCurrentTop + safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top) - <span class="reserved">this</span>.yOrigin;

    var vpTop = <span class="reserved">this</span>.nCurrentTop - deltaMouseY;
    var vpLeft = <span class="reserved">this</span>.nCurrentLeft - deltaMouseX;

    var vpCenterX = vpLeft + <span class="reserved">this</span>.viewportWidth/2;
    var vpCenterY = vpTop + <span class="reserved">this</span>.viewportHeight/2;

    var currentTileX = Math.floor(vpCenterX/<span class="reserved">this</span>.tileWidth)*<span class="reserved">this</span>.tileWidth;
    var currentTileY = Math.floor(vpCenterY/<span class="reserved">this</span>.tileHeight)*<span class="reserved">this</span>.tileHeight;

    var tileDeltaX = currentTileX - <span class="reserved">this</span>.nCurrentLeft;
    var tileDeltaY = currentTileY - <span class="reserved">this</span>.nCurrentTop;

    var newVpCenterX = vpCenterX * nFactor;
    var newVpCenterY = vpCenterY * nFactor;

    var newTileX = Math.floor(newVpCenterX/<span class="reserved">this</span>.tileWidth) * <span class="reserved">this</span>.tileWidth;
    var newTileY = Math.floor(newVpCenterY/<span class="reserved">this</span>.tileHeight) * <span class="reserved">this</span>.tileHeight;

    var newCurrentLeft = newTileX - tileDeltaX;
    var newCurrentTop = newTileY - tileDeltaY;

    <span class="reserved">this</span>.nCurrentLeft = newCurrentLeft;
    <span class="reserved">this</span>.nCurrentTop = newCurrentTop;

    var newTilLeft = -newVpCenterX + <span class="reserved">this</span>.viewportWidth/2;
    var newTilTop = -newVpCenterY + <span class="reserved">this</span>.viewportHeight/2;

    var xOldOrigin = <span class="reserved">this</span>.xOrigin;
    var yOldOrigin = <span class="reserved">this</span>.yOrigin;

    <span class="reserved">this</span>.xOrigin = <span class="reserved">this</span>.nCurrentLeft;
    <span class="reserved">this</span>.yOrigin = <span class="reserved">this</span>.nCurrentTop;

    <span class="reserved">this</span>.theInsideLayer.style.left = (newTilLeft + <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
    <span class="reserved">this</span>.theInsideLayer.style.top = (newTilTop + <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;

    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        <span class="reserved">for</span>(var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
            <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
                var img = d.childNodes[(j*<span class="reserved">this</span>.nWide)+i];
                img.src = <span class="reserved">this</span>.aPixel.src;
                img.style.top = (<span class="reserved">this</span>.nCurrentTop + j*<span class="reserved">this</span>.tileHeight - <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
                img.style.left = (<span class="reserved">this</span>.nCurrentLeft + i*<span class="reserved">this</span>.tileWidth - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
                layers[k].setTile(img);
            }
        }
    }
    <span class="reserved">this</span>.checkWrap();
    <span class="reserved">this</span>.updateObjects();
};

<span class="comment">/***************************************
 * internal function adedd by cappu
 * use to paint a layer calculating tile
 * position for current exten and scale
 * and calling the layer.seTile
 ***************************************/</span>
kaMap.<span class="reserved">prototype</span>.paintLayer = <span class="reserved">function</span>(l) {
     var d = l.domObj;
     <span class="reserved">for</span>(var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
         <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
             var img = d.childNodes[(j*<span class="reserved">this</span>.nWide)+i];
            <span class="comment">// img.src = this.aPixel.src;</span>
             img.style.top = (<span class="reserved">this</span>.nCurrentTop + j*<span class="reserved">this</span>.tileHeight - <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
             img.style.left = (<span class="reserved">this</span>.nCurrentLeft + i*<span class="reserved">this</span>.tileWidth - <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
             l.setTile(img);
         }
     }
     <span class="reserved">this</span>.checkWrap();
};

<span class="comment">/* kaMap.updateObjects
 * call this after any major change to the state of kaMap including after
 * a zoomTo, zoomToExtents, etc.
 */</span>
kaMap.<span class="reserved">prototype</span>.updateObjects = <span class="reserved">function</span>() {
    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.aObjects.length;i++) {
        var obj = <span class="reserved">this</span>.aObjects[i];
        var xOffset = (obj.xOffset) ? obj.xOffset : 0;
        var yOffset = (obj.yOffset) ? obj.yOffset : 0;
        var aPix = <span class="reserved">this</span>.geoToPix( obj.lon, obj.lat );
        var top = (aPix[1] - <span class="reserved">this</span>.yOrigin + yOffset);
        var left = (aPix[0] - <span class="reserved">this</span>.xOrigin + xOffset);
        obj.style.top = top + <span class="literal">"px"</span>;
        obj.style.left = left + <span class="literal">"px"</span>;
    }
};

<span class="comment">/**
 * kaMap.resize()
 *
 * called when the viewport layer changes size.  It is the responsibility
 * of the user of this API to track changes in viewport size and call this
 * function to update the map
 */</span>
kaMap.<span class="reserved">prototype</span>.resize = <span class="reserved">function</span>( ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.initializationState != 2) {
        <span class="reserved">return</span> false;
    }
    var newViewportWidth = <span class="reserved">this</span>.getObjectWidth(<span class="reserved">this</span>.domObj);
    var newViewportHeight = <span class="reserved">this</span>.getObjectHeight(<span class="reserved">this</span>.domObj);

    <span class="reserved">if</span> (<span class="reserved">this</span>.viewportWidth == null) {
        <span class="reserved">this</span>.theInsideLayer.style.top = (-1*<span class="reserved">this</span>.nCurrentTop + <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
        <span class="reserved">this</span>.theInsideLayer.style.left = (-1*<span class="reserved">this</span>.nCurrentLeft + <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
        <span class="reserved">this</span>.viewportWidth = newViewportWidth;
        <span class="reserved">this</span>.viewportHeight = newViewportHeight;
    }
    var newWide = Math.ceil((newViewportWidth / <span class="reserved">this</span>.tileWidth) + 2*<span class="reserved">this</span>.nBuffer);
    var newHigh = Math.ceil((newViewportHeight / <span class="reserved">this</span>.tileHeight) + 2*<span class="reserved">this</span>.nBuffer);

    <span class="reserved">this</span>.viewportWidth = newViewportWidth;
    <span class="reserved">this</span>.viewportHeight = newViewportHeight;

    <span class="reserved">if</span> (<span class="reserved">this</span>.nHigh == 0 &amp;&amp; <span class="reserved">this</span>.nWide == 0) {
        <span class="reserved">this</span>.nWide = newWide;
    }

    <span class="reserved">while</span> (<span class="reserved">this</span>.nHigh &lt; newHigh) {

        <span class="reserved">this</span>.appendRow();
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nHigh &gt; newHigh &amp;&amp; newHigh &gt; 3) {
        <span class="reserved">this</span>.removeRow();
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nWide &lt; newWide) {
        <span class="reserved">this</span>.appendColumn();
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nWide &gt; newWide &amp;&amp; newWide &gt; 3) {
        <span class="reserved">this</span>.removeColumn();
    }
    <span class="comment">//create image don't call layer.set tile so i need to do that!</span>
    var map = <span class="reserved">this</span>.getCurrentMap();
    var layers =map.getLayers();
    <span class="reserved">for</span>(i=0;i&lt;layers.length;i++) {
        layers[i].setTileLayer();
    }

    <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
    <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
};

<span class="comment">/**
 * internal function to create images for map tiles
 *
 * top - integer, the top of this image in pixels
 * left - integer, the left of this image in pixels
 * obj - object, the layer in which this image will reside
 */</span>
kaMap.<span class="reserved">prototype</span>.createImage = <span class="reserved">function</span>( top, left, obj ) {
    var img = document.createElement(<span class="literal">'img'</span>);
    img.src=<span class="reserved">this</span>.aPixel.src;
    img.width=<span class="reserved">this</span>.tileWidth;
    img.height=<span class="reserved">this</span>.tileHeight;
    <span class="comment">//first for firefox, rest for IE :(</span>
    img.setAttribute(<span class="literal">'style'</span>, <span class="literal">'position:absolute; top:'</span>+top+<span class="literal">'px; left:'</span>+left+<span class="literal">'px;'</span> );
    img.style.position = <span class="literal">'absolute'</span>;
    img.style.top = (top - <span class="reserved">this</span>.yOrigin)+<span class="literal">'px'</span>;
    img.style.left = (left - <span class="reserved">this</span>.xOrigin)+<span class="literal">'px'</span>;
    img.style.width = <span class="reserved">this</span>.tileWidth + <span class="literal">"px"</span>;
    img.style.height = <span class="reserved">this</span>.tileHeight + <span class="literal">"px"</span>;
    img.style.visibility = <span class="literal">'hidden'</span>;
    img.galleryimg = <span class="literal">"no"</span>; <span class="comment">//turn off image toolbar in IE</span>
    img.onerror = kaMap_imgOnError;
    img.onload = kaMap_imgOnLoad;
    img.errorCount = 0;
    img.id = <span class="literal">"i"</span> + <span class="reserved">this</span>.gImageID;
    img.layer = obj;
    img.kaMap = <span class="reserved">this</span>;
    <span class="reserved">this</span>.gImageID = <span class="reserved">this</span>.gImageID + 1;
    <span class="reserved">return</span> img;
};

kaMap.<span class="reserved">prototype</span>.resetTile = <span class="reserved">function</span>( id, bForce ) {
    var img = <span class="reserved">this</span>.DHTMLapi.getRawObject(id);
    <span class="reserved">if</span> (img.layer) {
        img.layer.setTile(<span class="reserved">this</span>, bForce);
    }
};

kaMap.<span class="reserved">prototype</span>.reloadImage = <span class="reserved">function</span>(id) {
};

kaMap.<span class="reserved">prototype</span>.resetImage = <span class="reserved">function</span>(id) {
};

<span class="comment">/**
 * internal function to handle images that fail to load
 */</span>
kaMap_imgOnError = <span class="reserved">function</span>(e) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.layer) {
        <span class="reserved">this</span>.layer.setTile(<span class="reserved">this</span>, true);
    }
};

<span class="comment">/**
 * internal function to track images as they finish loading.
 */</span>
kaMap_imgOnLoad = <span class="reserved">function</span>(e) {
    <span class="reserved">this</span>.style.visibility = <span class="literal">'visible'</span>;
};

<span class="comment">/**
 * internal function to append a row of images to each of the layers
 *
 * this function is used when the viewport is resized
 * modified by cappu can take a single layer as input
 */</span>
kaMap.<span class="reserved">prototype</span>.appendRow = <span class="reserved">function</span>(layer) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.nWide == 0) {
        <span class="reserved">return</span>;
    }
    var layers = null;
    <span class="reserved">if</span>(arguments.length==1) {
        layers = Array(layer);
    } <span class="reserved">else</span> {
        layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    }
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        var obj = layers[i].domObj;
        <span class="reserved">for</span> (var j=0; j&lt;<span class="reserved">this</span>.nWide; j++) {
            var top = <span class="reserved">this</span>.nCurrentTop + (<span class="reserved">this</span>.nHigh * <span class="reserved">this</span>.tileHeight);
            var left = <span class="reserved">this</span>.nCurrentLeft + (j * <span class="reserved">this</span>.tileWidth);
            var img = <span class="reserved">this</span>.createImage( top, left, layers[i] );
            <span class="comment">//hack around IE problem with clipping layers when a filter is</span>
            <span class="comment">//active</span>
            <span class="reserved">if</span> (<span class="reserved">this</span>.isIE4) {
                img.style.filter = <span class="literal">"Alpha(opacity="</span>+layers[i].opacity+<span class="literal">")"</span>;
            }
            obj.appendChild( img );
        }
    }
    <span class="reserved">this</span>.nHigh = <span class="reserved">this</span>.nHigh + 1;
};

<span class="comment">/**
 * internal function to append a column of images to each of the layers
 *
 * this function is used when the viewport is resized
 * modified by cappu can take a single layer as input
 */</span>
kaMap.<span class="reserved">prototype</span>.appendColumn = <span class="reserved">function</span>(layer) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.nHigh == 0) {
        <span class="reserved">return</span>;
    }
    var layers = null;
    <span class="reserved">if</span>(arguments.length==1) {
        layers = Array(layer);
    } <span class="reserved">else</span> {
        layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    }
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        var obj = layers[i].domObj;
        <span class="reserved">for</span>(var j=<span class="reserved">this</span>.nHigh-1; j&gt;=0; j--) {
            var top = <span class="reserved">this</span>.nCurrentTop + (j * <span class="reserved">this</span>.tileHeight);
            var left = <span class="reserved">this</span>.nCurrentLeft + (<span class="reserved">this</span>.nWide * <span class="reserved">this</span>.tileWidth);
            var img = <span class="reserved">this</span>.createImage( top, left, layers[i] );
            <span class="comment">//hack around IE problem with clipping layers when a filter is</span>
            <span class="comment">//active</span>
            <span class="reserved">if</span> (<span class="reserved">this</span>.isIE4) {
                img.style.filter = <span class="literal">"Alpha(opacity="</span>+layers[i].opacity+<span class="literal">")"</span>;
            }
            <span class="reserved">if</span> (j &lt; <span class="reserved">this</span>.nHigh-1) {
                obj.insertBefore(img, obj.childNodes[((j+1)*<span class="reserved">this</span>.nWide)]);
            } <span class="reserved">else</span> {
                obj.appendChild(img);
            }
         }
    }
    <span class="reserved">this</span>.nWide = <span class="reserved">this</span>.nWide + 1;
};

<span class="comment">/**
 * internal function to remove a column of images to each of the layers
 *
 * this function is used when the viewport is resized
 * modified by cappu can take a single layer as input
 */</span>
kaMap.<span class="reserved">prototype</span>.removeColumn = <span class="reserved">function</span>(layer) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.nWide &lt; 3) {
        <span class="reserved">return</span>;
    }
    var layers = null;
    <span class="reserved">if</span>(arguments.length==1) {
        layers = Array(layer);
    } <span class="reserved">else</span> {
        layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    }
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        var d = layers[i].domObj;
        <span class="reserved">for</span>(var j=<span class="reserved">this</span>.nHigh - 1; j &gt;= 0; j--) {
            var img = d.childNodes[((j+1)*<span class="reserved">this</span>.nWide)-1];
            d.removeChild( img );
            <span class="comment">//attempt to prevent memory leaks</span>
            img.onload = null;
            img.onerror = null;
        }
    }
    <span class="reserved">this</span>.nWide = <span class="reserved">this</span>.nWide - 1;
};

<span class="comment">/**
 * internal function to remove a row of images to each of the layers
 *
 * this function is used when the viewport is resized
 * modified by cappu can take a single layer as input
 */</span>
kaMap.<span class="reserved">prototype</span>.removeRow = <span class="reserved">function</span>(layer) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.nHigh &lt; 3) {
        <span class="reserved">return</span>;
    }

    var layers = null;
    <span class="reserved">if</span>(arguments.length==1) {
        layers = Array(layer);
    } <span class="reserved">else</span> {
        layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    }

    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        var d = layers[i].domObj;
        <span class="reserved">for</span>(var j=<span class="reserved">this</span>.nWide - 1; j &gt;= 0; j--) {
            var img = d.childNodes[((<span class="reserved">this</span>.nHigh-1)*<span class="reserved">this</span>.nWide)+j];
            d.removeChild( img );
            <span class="comment">//attempt to prevent memory leaks</span>
            img.onload = null;
            img.onerror = null;
        }
    }
    <span class="reserved">this</span>.nHigh = <span class="reserved">this</span>.nHigh - 1;
};

kaMap.<span class="reserved">prototype</span>.hideLayers = <span class="reserved">function</span>() {
    <span class="reserved">if</span> (!<span class="reserved">this</span>.hideLayersOnMove) {
        <span class="reserved">return</span>;
    }

    <span class="reserved">if</span> (<span class="reserved">this</span>.layersHidden) {
        <span class="reserved">return</span>;
    }
    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        layers[i]._visible = layers[i].visible;
        <span class="reserved">if</span> (layers[i].name != <span class="literal">'__base__'</span>) {
            layers[i].setVisibility( false );
        }
    }
    <span class="reserved">for</span>( var i = 0; i &lt; <span class="reserved">this</span>.aCanvases.length; i++) {
        <span class="reserved">this</span>.aCanvases[i].style.visibility = <span class="literal">'hidden'</span>;
        <span class="reserved">this</span>.aCanvases[i].style.display = <span class="literal">'none'</span>;
    }
    <span class="reserved">this</span>.layersHidden = true;
};

kaMap.<span class="reserved">prototype</span>.showLayers = <span class="reserved">function</span>() {
    <span class="reserved">if</span> (!<span class="reserved">this</span>.hideLayersOnMove) {
        <span class="reserved">return</span>;
    }

    <span class="reserved">if</span> (!<span class="reserved">this</span>.layersHidden) {
        <span class="reserved">return</span>;
    }
    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        layers[i].setVisibility( layers[i]._visible );
    }
    <span class="reserved">for</span>( var i = 0; i &lt; <span class="reserved">this</span>.aCanvases.length; i++) {
        <span class="reserved">this</span>.aCanvases[i].style.visibility = <span class="literal">'visible'</span>;
        <span class="reserved">this</span>.aCanvases[i].style.display = <span class="literal">'block'</span>;
    }
    <span class="reserved">this</span>.layersHidden = false;
};

<span class="comment">/**
 * move the map by a certain amount
 */</span>
kaMap.<span class="reserved">prototype</span>.moveBy = <span class="reserved">function</span>( x, y ) {
    var til = <span class="reserved">this</span>.theInsideLayer;
    til.style.top = (safeParseInt(til.style.top)+y) + <span class="literal">'px'</span>;
    til.style.left = (safeParseInt(til.style.left)+x )+ <span class="literal">'px'</span>;
    <span class="reserved">this</span>.checkWrap();
};

<span class="comment">/**
 * slide the map by a certain amount
 */</span>
kaMap.<span class="reserved">prototype</span>.slideBy = <span class="reserved">function</span>(x,y) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.slideid!=null) {
        goQueueManager.dequeue( <span class="reserved">this</span>.slideid );
    }

    <span class="reserved">this</span>.as = [];

    var absX = Math.abs(x);
    var absY = Math.abs(y);

    var signX = x/absX;
    var signY = y/absY;

    var distance = absX&gt;absY?absX:absY;
    var steps = Math.floor(distance/<span class="reserved">this</span>.pixelsPerStep);

    var dx = dy = 0;
    <span class="reserved">if</span> (steps &gt; 0) {
        dx = (x)/(steps*<span class="reserved">this</span>.pixelsPerStep);
        dy = (y)/(steps*<span class="reserved">this</span>.pixelsPerStep);
    }

    var remainderX = x - dx*steps*<span class="reserved">this</span>.pixelsPerStep;
    var remainderY = y - dy*steps*<span class="reserved">this</span>.pixelsPerStep;

    var px=py=0;

    var curspeed=<span class="reserved">this</span>.accelerationFactor;
    var i=0;
    <span class="reserved">while</span>(i&lt;steps) {
        <span class="reserved">if</span> (i&gt;0) {
          px+=<span class="reserved">this</span>.as[i-1][0];
          py+=<span class="reserved">this</span>.as[i-1][1];
        }

        var cx = px+Math.round(dx*<span class="reserved">this</span>.pixelsPerStep);
        var cy = py+Math.round(dy*<span class="reserved">this</span>.pixelsPerStep);
        <span class="reserved">this</span>.as[i]=new Array(cx-px,cy-py);
        i++;
    }
    <span class="reserved">if</span> (remainderX != 0 || remainderY != 0) {
        <span class="reserved">this</span>.as[i] = [remainderX, remainderY];
    }
    <span class="reserved">this</span>.hideLayers();
    <span class="reserved">this</span>.slideid=goQueueManager.enqueue(<span class="reserved">this</span>.timePerStep,<span class="reserved">this</span>,<span class="reserved">this</span>.slide,[0]);
};

<span class="comment">/**
 * handle individual movement within a slide
 */</span>
kaMap.<span class="reserved">prototype</span>.slide = <span class="reserved">function</span>(pos) {
    <span class="reserved">if</span> (pos&gt;=<span class="reserved">this</span>.as.length) {
        <span class="reserved">this</span>.as=slideid=null;
        <span class="reserved">this</span>.showLayers();
        <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
        <span class="reserved">return</span>;
    }

    <span class="reserved">this</span>.moveBy( <span class="reserved">this</span>.as[pos][0], <span class="reserved">this</span>.as[pos][1] );

    pos ++;
    <span class="reserved">this</span>.slideid=goQueueManager.enqueue(<span class="reserved">this</span>.timePerStep,<span class="reserved">this</span>,<span class="reserved">this</span>.slide,[ pos]);
};

<span class="comment">/**
 * internal function to handle various events that are passed to the
 * current tool
 */</span>
kaMap_onkeypress = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onkeypress( e );
    }
};

kaMap_onmousemove = <span class="reserved">function</span>( e ) {
    e = (e)?e:((event)?event:null);
    <span class="reserved">if</span> (e.button==2) {
        <span class="reserved">this</span>.kaMap.triggerEvent( KAMAP_CONTEXT_MENU );
    }
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmousemove( e );
    }
};

kaMap_onmousedown = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmousedown( e );
    }
};

kaMap_onmouseup = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmouseup( e );
    }
};

kaMap_onmouseover = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmouseover( e );
    }
};

kaMap_onmouseout = <span class="reserved">function</span>( e ) {
     <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmouseout( e );
    }
};

kaMap_oncontextmenu = <span class="reserved">function</span>( e ) {
    e = e?e:event;
    <span class="reserved">if</span> (e.preventDefault) {
        e.preventDefault();
    }
    <span class="reserved">return</span> false;
};

kaMap_ondblclick = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.ondblclick( e );
    }
};

kaMap_onmousewheel = <span class="reserved">function</span>( e ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.kaMap.currentTool) {
        <span class="reserved">this</span>.kaMap.currentTool.onmousewheel( e );
    }
};

kaMap.<span class="reserved">prototype</span>.cancelEvent = <span class="reserved">function</span>(e) {
    e = (e)?e:((event)?event:null);
    e.returnValue = false;
    <span class="reserved">if</span> (e.preventDefault) {
        e.preventDefault();
    }
    <span class="reserved">return</span> false;
};

kaMap.<span class="reserved">prototype</span>.registerTool = <span class="reserved">function</span>( toolObj ) {
    <span class="reserved">this</span>.aTools.push( toolObj );
};

kaMap.<span class="reserved">prototype</span>.activateTool = <span class="reserved">function</span>( toolObj ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.currentTool) {
        <span class="reserved">this</span>.currentTool.deactivate();
    }
    <span class="reserved">this</span>.currentTool = toolObj;
    <span class="reserved">if</span> (<span class="reserved">this</span>.theInsideLayer) {
        <span class="reserved">this</span>.setCursor(<span class="reserved">this</span>.currentTool.cursor);
    }
};

kaMap.<span class="reserved">prototype</span>.deactivateTool = <span class="reserved">function</span>( toolObj ) {

    <span class="reserved">if</span> (<span class="reserved">this</span>.currentTool == toolObj) {
        <span class="reserved">this</span>.currentTool = null;
    }
    <span class="reserved">if</span> (<span class="reserved">this</span>.theInsideLayer) {
        <span class="reserved">this</span>.theInsideLayer.style.cursor = <span class="literal">'auto'</span>;
    }
};

<span class="comment">/*
 * inspired by code in WindowManager.js
 * Copyright 2005 MetaCarta, Inc., released under the BSD License
 */</span>
kaMap.<span class="reserved">prototype</span>.setCursor = <span class="reserved">function</span>(cursor) {
    <span class="reserved">if</span> (cursor &amp;&amp; cursor.length &amp;&amp; typeof cursor == <span class="literal">'object'</span>) {
        <span class="reserved">for</span> (var i = 0; i &lt; cursor.length; i++) {
            <span class="reserved">this</span>.theInsideLayer.style.cursor = cursor[i];
            <span class="reserved">if</span> (<span class="reserved">this</span>.theInsideLayer.style.cursor == cursor[i]) {
                break;
            }
        }
    } <span class="reserved">else</span> <span class="reserved">if</span> (typeof cursor == <span class="literal">'string'</span>) {
        <span class="reserved">this</span>.theInsideLayer.style.cursor = cursor;
    } <span class="reserved">else</span> {
        <span class="reserved">this</span>.theInsideLayer.style.cursor = <span class="literal">'auto'</span>;
    }
};

<span class="comment">/**
 * internal function to check if images need to be wrapped
 */</span>
kaMap.<span class="reserved">prototype</span>.checkWrap = <span class="reserved">function</span>() {
    var bWrapped = false;
    <span class="comment">// adjust theInsideLayer so it doesn't show more than maxExtents (if set)</span>
    <span class="reserved">this</span>.checkMaxExtents();

    <span class="reserved">this</span>.xOffset = safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left) + <span class="reserved">this</span>.nCurrentLeft - <span class="reserved">this</span>.xOrigin;
    <span class="reserved">this</span>.yOffset = safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top) + <span class="reserved">this</span>.nCurrentTop - <span class="reserved">this</span>.yOrigin;

    <span class="reserved">while</span> (<span class="reserved">this</span>.xOffset &gt; 0) {
        <span class="reserved">this</span>.wrapR2L();
        bWrapped = true;
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.xOffset &lt; -(<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileWidth)) {
        <span class="reserved">this</span>.wrapL2R();
        bWrapped = true;
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.yOffset &gt; -(<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileHeight)) {
        <span class="reserved">this</span>.wrapB2T();
        bWrapped = true;
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.yOffset &lt; -(2*<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileHeight)) {
        <span class="reserved">this</span>.wrapT2B();
        bWrapped = true;
    }

    var layer = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].aLayers[0].domObj;
    var img = layer.childNodes[0].style;
    <span class="reserved">this</span>.nCurrentTop = safeParseInt(img.top) + <span class="reserved">this</span>.yOrigin;
    <span class="reserved">this</span>.nCurrentLeft = safeParseInt(img.left) + <span class="reserved">this</span>.xOrigin;

    <span class="reserved">if</span> (bWrapped) {
        <span class="reserved">this</span>.triggerEvent( KAMAP_METAEXTENTS_CHANGED, <span class="reserved">this</span>.getMetaExtents() );
    }
};

<span class="comment">/**
 * kaMap.checkMaxExtents()
 *
 * For maps with maxExtent set, this function adjusts the position of
 * theInsideLayer so it never shows more than the maximum extent specified
 * in the mapfile.  Called from kaMap.checkWrap() since that is called
 * with all movement of theInsideLayer
 *
 * Added by tschaub
 */</span>
kaMap.<span class="reserved">prototype</span>.checkMaxExtents = <span class="reserved">function</span>() {
    var maxExtents = <span class="reserved">this</span>.getCurrentMap().maxExtents;
    <span class="reserved">if</span> (maxExtents.length == 4) {
		<span class="reserved">if</span> ((maxExtents[0] &gt;= maxExtents[2]) || (maxExtents[1] &gt;= maxExtents[3])) {
			<span class="comment">// fail silently</span>
			<span class="reserved">return</span> false;
		}
        var geoExtents = <span class="reserved">this</span>.getGeoExtents();
        var hPixelAdjustment = 0;
        var vPixelAdjustment = 0;
        <span class="comment">// check left and right</span>
        <span class="reserved">if</span> (geoExtents[0] &lt; maxExtents[0]) {
            <span class="comment">// extra on right</span>
            hPixelAdjustment = Math.round((maxExtents[0] - geoExtents[0]) / <span class="reserved">this</span>.cellSize);
        }
        <span class="reserved">if</span> (geoExtents[2] &gt; maxExtents[2]) {
            <span class="comment">// extra on left</span>
			<span class="reserved">if</span>(hPixelAdjustment != 0)
			{
				<span class="comment">// if both left and right are over, split the difference</span>
	            hPixelAdjustment += Math.round((maxExtents[2] - geoExtents[2]) / <span class="reserved">this</span>.cellSize);
				hPixelAdjustment /= 2;
			} <span class="reserved">else</span> {
				hPixelAdjustment += Math.round((maxExtents[2] - geoExtents[2]) / <span class="reserved">this</span>.cellSize);
			}
        }
		<span class="comment">// check if horizontal adjustment is needed</span>
		<span class="reserved">if</span>(hPixelAdjustment != 0) {
            <span class="reserved">this</span>.theInsideLayer.style.left = (safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left) - hPixelAdjustment) + <span class="literal">'px'</span>;
        }
        <span class="comment">// check top and bottom - both can not be corrected</span>
        <span class="reserved">if</span>(geoExtents[1] &lt; maxExtents[1]) {
            <span class="comment">// extra on bottom</span>
            vPixelAdjustment = Math.round((maxExtents[1] - geoExtents[1]) / <span class="reserved">this</span>.cellSize);
        }
        <span class="reserved">if</span>(geoExtents[3] &gt; maxExtents[3]) {
            <span class="comment">// extra on top</span>
			<span class="reserved">if</span>(vPixelAdjustment != 0) {
				<span class="comment">// if both top and bottom are over, split the difference</span>
	            vPixelAdjustment += Math.round((maxExtents[3] - geoExtents[3]) / <span class="reserved">this</span>.cellSize);
				vPixelAdjustment /= 2;
			} <span class="reserved">else</span> {
	            vPixelAdjustment = Math.round((maxExtents[3] - geoExtents[3]) / <span class="reserved">this</span>.cellSize);
			}
        }
		<span class="reserved">if</span>(vPixelAdjustment != 0) {
            <span class="reserved">this</span>.theInsideLayer.style.top = (safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top) + vPixelAdjustment) + <span class="literal">'px'</span>;
        }
    }
};

<span class="comment">/**
 * internal function to reuse extra images
 * take last image from each row and put it at the beginning
 */</span>
kaMap.<span class="reserved">prototype</span>.wrapR2L = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.xOffset = <span class="reserved">this</span>.xOffset - (<span class="reserved">this</span>.nBuffer * <span class="reserved">this</span>.tileWidth);

    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        var refLeft = safeParseInt(d.childNodes[0].style.left);
        <span class="reserved">for</span> (var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
            var imgLast = d.childNodes[((j+1)*<span class="reserved">this</span>.nWide)-1];
            var imgNext = d.childNodes[j*<span class="reserved">this</span>.nWide];

            imgLast.style.left = (refLeft - <span class="reserved">this</span>.tileWidth) + <span class="literal">'px'</span>;
            imgLast.src = <span class="reserved">this</span>.aPixel.src;
            d.removeChild(imgLast);
            d.insertBefore(imgLast, imgNext);
            <span class="reserved">if</span> (layers[k].visible) {
                layers[k].setTile(imgLast);
            }
        }
    }
};

<span class="comment">/**
 * internal function to reuse extra image
 * take first image from each row and put it at the end
 */</span>
kaMap.<span class="reserved">prototype</span>.wrapL2R = <span class="reserved">function</span>() {
     <span class="reserved">this</span>.xOffset = <span class="reserved">this</span>.xOffset + (<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileWidth);
    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        var refLeft = safeParseInt(d.childNodes[<span class="reserved">this</span>.nWide-1].style.left);
        <span class="reserved">for</span> (var j=0; j&lt;<span class="reserved">this</span>.nHigh; j++) {
            var imgFirst = d.childNodes[j*<span class="reserved">this</span>.nWide];
            var imgNext;
            <span class="comment">/* need to use insertBefore to get a node at the end of a 'row'
             * but this doesn't work for the very last row :(*/</span>
            <span class="reserved">if</span> (j &lt; <span class="reserved">this</span>.nHigh-1) {
                imgNext = d.childNodes[((j+1)*<span class="reserved">this</span>.nWide)];
            } <span class="reserved">else</span> {
                imgNext = null;
            }

            imgFirst.style.left = (refLeft + <span class="reserved">this</span>.tileWidth) + <span class="literal">'px'</span>;
            imgFirst.src = <span class="reserved">this</span>.aPixel.src;

            d.removeChild(imgFirst);
            <span class="reserved">if</span> (imgNext) {
                d.insertBefore(imgFirst, imgNext);
            } <span class="reserved">else</span> {
                d.appendChild(imgFirst);
            }
            <span class="reserved">if</span> (layers[k].visible) {
                layers[k].setTile(imgFirst);
            }
        }
    }
};

<span class="comment">/**
 * internal function to reuse extra images
 * take top image from each column and put it at the bottom
 */</span>
kaMap.<span class="reserved">prototype</span>.wrapT2B = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.yOffset = <span class="reserved">this</span>.yOffset + (<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileHeight);
    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        var refTop = safeParseInt(d.childNodes[(<span class="reserved">this</span>.nHigh*<span class="reserved">this</span>.nWide)-1].style.top);
        <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
            var imgBottom = d.childNodes[0];
            imgBottom.style.top = (refTop + <span class="reserved">this</span>.tileHeight) + <span class="literal">'px'</span>;
            imgBottom.src = <span class="reserved">this</span>.aPixel.src;
            d.removeChild(imgBottom);
            d.appendChild(imgBottom);
            <span class="reserved">if</span> (layers[k].visible) {
                layers[k].setTile(imgBottom);
            }
        }
    }
};

<span class="comment">/**
 * internal function to reuse extra images
 * take bottom image from each column and put it at the top
 */</span>
kaMap.<span class="reserved">prototype</span>.wrapB2T = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.yOffset = <span class="reserved">this</span>.yOffset - (<span class="reserved">this</span>.nBuffer*<span class="reserved">this</span>.tileHeight);
    var layers = <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayers();
    <span class="reserved">for</span>( var k=0; k&lt;layers.length; k++) {
        var d = layers[k].domObj;
        var refTop = safeParseInt(d.childNodes[0].style.top);
        <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.nWide; i++) {
            var imgTop = d.childNodes[(<span class="reserved">this</span>.nHigh*<span class="reserved">this</span>.nWide)-1];

            imgTop.style.top = (refTop - <span class="reserved">this</span>.tileHeight) + <span class="literal">'px'</span>;
            imgTop.src = <span class="reserved">this</span>.aPixel.src;

            d.removeChild(imgTop);
            d.insertBefore(imgTop, d.childNodes[0]);
            <span class="reserved">if</span> (layers[k].visible) {
                layers[k].setTile(imgTop);
            }

        }
    }
};

<span class="comment">/**
 * kaMap.addMap( oMap )
 *
 * add a new instance of _map to kaMap.  _map is an internal class that
 * represents a map file from the configuration file.  This function is
 * intended for internal use by the init.php script.
 *
 * oMap - object, an instance of _map
 */</span>
kaMap.<span class="reserved">prototype</span>.addMap = <span class="reserved">function</span>( oMap ) {
    oMap.kaMap = <span class="reserved">this</span>;
    <span class="reserved">this</span>.aMaps[oMap.name] = oMap;
};

<span class="comment">/**
 * kaMap.getMaps()
 *
 * return an array of all the _map objects that kaMap knows about.  These can
 * be used to generate controls to switch between maps and to get information
 * about the layers (groups) and scales available in a given map.
 */</span>
kaMap.<span class="reserved">prototype</span>.getMaps = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.aMaps;
};

<span class="comment">/**
 * kaMap.getCurrentMap()
 *
 * returns the currently selected _map object.  This can be used to get
 * information about the layers (groups) and scales available in the current
 * map.
 */</span>
kaMap.<span class="reserved">prototype</span>.getCurrentMap = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap];
};

<span class="comment">/**
 * kaMap.selectMap( name )
 *
 * select one of the maps that kaMap knows about and re-initialize kaMap with
 * this new map.  This function returns true if name is valid and false if the
 * map is invalid.  Note that a return of true does not imply that the map is
 * fully active.  You must register for the KAMAP_MAP_INITIALIZED event since
 * the map initialization happens asynchronously.
 *
 * name - string, the name of the map to select
 */</span>
kaMap.<span class="reserved">prototype</span>.selectMap = <span class="reserved">function</span>( name ) {
    <span class="reserved">if</span> (!<span class="reserved">this</span>.aMaps[name]) {
        <span class="reserved">return</span> false;
    } <span class="reserved">else</span> {
        <span class="reserved">this</span>.currentMap = name;
        var oMap = <span class="reserved">this</span>.getCurrentMap();
        <span class="reserved">this</span>.setBackgroundColor(oMap.backgroundColor);

        <span class="comment">//modified by cappu</span>
        <span class="reserved">this</span>.setMapLayers();
        <span class="reserved">if</span> (oMap.aZoomTo.length != 0) {
            <span class="reserved">this</span>.zoomTo(oMap.aZoomTo[0], oMap.aZoomTo[1], oMap.aZoomTo[2]);
            oMap.aZoomTo.length = 0;
        } <span class="reserved">else</span> {
            <span class="reserved">this</span>.zoomToExtents( oMap.currentExtents[0], oMap.currentExtents[1],
                               oMap.currentExtents[2], oMap.currentExtents[3] );
        }
        <span class="reserved">this</span>.triggerEvent( KAMAP_MAP_INITIALIZED, <span class="reserved">this</span>.currentMap );
        <span class="reserved">return</span> true;
    }
};

<span class="comment">/*
 * internal function added by cappu
 * check wich layers are visible and checked visible
 * in legend for current scale and map in InsideLayer
 * If needed create append or remove mapLayer!
 */</span>
kaMap.<span class="reserved">prototype</span>.setMapLayers = <span class="reserved">function</span>( ) {
    var oMap = <span class="reserved">this</span>.getCurrentMap();
    <span class="comment">//remove layers not to be drown at the selected scale this should be change to not remove the visible</span>
    <span class="reserved">for</span>(var i = <span class="reserved">this</span>.theInsideLayer.childNodes.length - 1; i&gt;=0; i-- ) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.theInsideLayer.childNodes[i].className == <span class="literal">'mapLayer'</span>) {
            <span class="reserved">this</span>.theInsideLayer.childNodes[i].appended=false;
            <span class="reserved">this</span>.theInsideLayer.removeChild(<span class="reserved">this</span>.theInsideLayer.childNodes[i]);        }
    }
   <span class="comment">//now check layer and create or append</span>
    layers=oMap.getLayers(); <span class="comment">//get only visible and checked layers</span>
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        <span class="reserved">if</span>(!layers[i].domObj) {
            var d = <span class="reserved">this</span>.createMapLayer( layers[i].name );
            <span class="reserved">this</span>.theInsideLayer.appendChild( d );
            d.appended=true;
            layers[i].domObj = d;
            layers[i].setOpacity( layers[i].opacity );
            layers[i].setZIndex( layers[i].zIndex );
            layers[i].setVisibility( layers[i].visible );
            <span class="reserved">this</span>.nWide = 0;
            <span class="reserved">this</span>.nHigh = 0;
            <span class="reserved">this</span>.drawGroup(layers[i]);
        } <span class="reserved">else</span> <span class="reserved">if</span> (!layers[i].domObj.appended) {
            <span class="reserved">this</span>.theInsideLayer.appendChild( layers[i].domObj );
            layers[i].domObj.appended=true;
            layers[i].setZIndex( layers[i].zIndex );
        }
    }
    <span class="reserved">return</span> true;
};

<span class="comment">/*
 * internal function added by cappu
 * this function force a layer create image
 */</span>
kaMap.<span class="reserved">prototype</span>.drawGroup = <span class="reserved">function</span>(group) {
    var newViewportWidth = <span class="reserved">this</span>.getObjectWidth(<span class="reserved">this</span>.domObj);
    var newViewportHeight = <span class="reserved">this</span>.getObjectHeight(<span class="reserved">this</span>.domObj);

    <span class="reserved">if</span> (<span class="reserved">this</span>.viewportWidth == null) {
        <span class="reserved">this</span>.theInsideLayer.style.top = (-1*<span class="reserved">this</span>.nCurrentTop + <span class="reserved">this</span>.yOrigin) + <span class="literal">"px"</span>;
        <span class="reserved">this</span>.theInsideLayer.style.left = (-1*<span class="reserved">this</span>.nCurrentLeft + <span class="reserved">this</span>.xOrigin) + <span class="literal">"px"</span>;
        <span class="reserved">this</span>.viewportWidth = newViewportWidth;
        <span class="reserved">this</span>.viewportHeight = newViewportHeight;
    }
    var newWide = Math.ceil((newViewportWidth / <span class="reserved">this</span>.tileWidth) + 2*<span class="reserved">this</span>.nBuffer);
    var newHigh = Math.ceil((newViewportHeight / <span class="reserved">this</span>.tileHeight) + 2*<span class="reserved">this</span>.nBuffer);

    <span class="reserved">this</span>.viewportWidth = newViewportWidth;
    <span class="reserved">this</span>.viewportHeight = newViewportHeight;

    <span class="reserved">if</span> (<span class="reserved">this</span>.nHigh == 0 &amp;&amp; <span class="reserved">this</span>.nWide == 0) {
        <span class="reserved">this</span>.nWide = newWide;
    }

    <span class="reserved">while</span> (<span class="reserved">this</span>.nHigh &lt; newHigh) {
        <span class="reserved">this</span>.appendRow(group);
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nHigh &gt; newHigh) {
        <span class="reserved">this</span>.removeRow(group);
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nWide &lt; newWide) {
        <span class="reserved">this</span>.appendColumn(group);
    }
    <span class="reserved">while</span> (<span class="reserved">this</span>.nWide &gt; newWide) {
        <span class="reserved">this</span>.removeColumn(group);
    }
    <span class="reserved">return</span> true;
};

kaMap.<span class="reserved">prototype</span>.createMapLayer = <span class="reserved">function</span>( id ) {
    var d = document.createElement( <span class="literal">'div'</span> );
    d.id = id;
    d.className = <span class="literal">'mapLayer'</span>;
    d.style.position = <span class="literal">'absolute'</span>;
    d.style.visibility = <span class="literal">'visible'</span>;
    d.style.left = <span class="literal">'0px'</span>;
    d.style.top = <span class="literal">'0px'</span>;
    d.style.width= <span class="literal">'3000px'</span>;
    d.style.height = <span class="literal">'3000px'</span>;
    d.appended= false;<span class="comment">//added by cappu</span>
    <span class="reserved">return</span> d;
};

<span class="comment">//modified by cappu</span>
kaMap.<span class="reserved">prototype</span>.addMapLayer = <span class="reserved">function</span>( l ) {
    var map = <span class="reserved">this</span>.getCurrentMap();
    map.addLayer(l);
    <span class="reserved">this</span>.setMapLayers();
    <span class="reserved">this</span>.paintLayer(l);
    <span class="reserved">this</span>.triggerEvent( KAMAP_LAYERS_CHANGED, <span class="reserved">this</span>.currentMap );
};

<span class="comment">//added by cappu</span>
kaMap.<span class="reserved">prototype</span>.removeMapLayer = <span class="reserved">function</span>( id ) {
    var map = <span class="reserved">this</span>.getCurrentMap();
    var layer = map.getLayer(id);
    <span class="reserved">if</span> (!layer) {
        <span class="reserved">return</span> false;
    }
    <span class="reserved">if</span> (map.removeLayer ( map.getLayer(id) )) {
        <span class="reserved">this</span>.setMapLayers();
        <span class="reserved">this</span>.triggerEvent( KAMAP_LAYERS_CHANGED, <span class="reserved">this</span>.currentMap );
    }
};

kaMap.<span class="reserved">prototype</span>.getCenter = <span class="reserved">function</span>() {
    var deltaMouseX = <span class="reserved">this</span>.nCurrentLeft - <span class="reserved">this</span>.xOrigin + safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left);
    var deltaMouseY = <span class="reserved">this</span>.nCurrentTop - <span class="reserved">this</span>.yOrigin +  safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top);

    var vpTop = <span class="reserved">this</span>.nCurrentTop - deltaMouseY;
    var vpLeft = <span class="reserved">this</span>.nCurrentLeft - deltaMouseX;

    var vpCenterX = vpLeft + <span class="reserved">this</span>.viewportWidth/2;
    var vpCenterY = vpTop + <span class="reserved">this</span>.viewportHeight/2;

    <span class="reserved">return</span> new Array( vpCenterX, vpCenterY );
};

<span class="comment">/**
 * kaMap.getGeoExtents()
 *
 * returns an array of geographic extents for the current view in the form
 * (inx, miny, maxx, maxy)
 */</span>
kaMap.<span class="reserved">prototype</span>.getGeoExtents = <span class="reserved">function</span>() {
    var minx = -1*(safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.left) - <span class="reserved">this</span>.xOrigin) * <span class="reserved">this</span>.cellSize;
    var maxx = minx + <span class="reserved">this</span>.viewportWidth * <span class="reserved">this</span>.cellSize;
    var maxy= (safeParseInt(<span class="reserved">this</span>.theInsideLayer.style.top) - <span class="reserved">this</span>.yOrigin) * <span class="reserved">this</span>.cellSize;
    var miny= maxy - <span class="reserved">this</span>.viewportHeight * <span class="reserved">this</span>.cellSize;
    <span class="reserved">return</span> [minx,miny,maxx,maxy];
};

<span class="comment">/**
 * kaMap.getMetaExtents()
 *
 * returns an array of geographic extents for the loaded tiles in the form
 * (minx, miny, maxx, maxy)
 */</span>
kaMap.<span class="reserved">prototype</span>.getMetaExtents = <span class="reserved">function</span>() {
    <span class="comment">//use current extents if no layers visible</span>
    var result = <span class="reserved">this</span>.getGeoExtents();
    var oMap = <span class="reserved">this</span>.getCurrentMap();
    layers=oMap.getLayers();
    <span class="reserved">for</span>( var i=0; i&lt;layers.length; i++) {
        <span class="comment">//find first layer with a domObj</span>
        <span class="reserved">if</span>(layers[i].domObj) {
            var d = layers[i].domObj;
            <span class="comment">//top left of first image should be top left of loaded tiles</span>
            var pl = safeParseInt(d.childNodes[0].style.left);
            var pt = safeParseInt(d.childNodes[0].style.top);
            <span class="comment">/*  I think the first child is always top left ...
            for (var j=0;j&lt;d.childNodes.length; j++) {
                if (pl == null) {
                    pl = safeParseInt(d.childNodes[j].style.left);
                    pt = safeParseInt(d.childNodes[j].style.top);
                } else {
                    pl = Math.min(pl,safeParseInt(d.childNodes[j].style.left));
                    pt = Math.min(pt,safeParseInt(d.childNodes[j].style.top));
                }
            }
            */</span>
            <span class="comment">//convert to geographic</span>
            var glt = <span class="reserved">this</span>.pixToGeo(pl,pt,true);
            var left = -1*glt[0];
            var top = -1*glt[1];
            <span class="comment">//bottom right is easy to calculate from this</span>
            var right = left + <span class="reserved">this</span>.nWide*<span class="reserved">this</span>.tileWidth*<span class="reserved">this</span>.cellSize;
            var bottom = top - <span class="reserved">this</span>.nHigh*<span class="reserved">this</span>.tileHeight*<span class="reserved">this</span>.cellSize;
            result = [left, bottom, right, top];
            break;
        }
    }
    <span class="reserved">return</span> result;
};

kaMap.<span class="reserved">prototype</span>.zoomIn = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.zoomByFactor(<span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].zoomIn());
};

kaMap.<span class="reserved">prototype</span>.zoomOut = <span class="reserved">function</span>() {
    <span class="reserved">this</span>.zoomByFactor(<span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].zoomOut());
};

kaMap.<span class="reserved">prototype</span>.zoomToScale = <span class="reserved">function</span>( scale ) {
    <span class="reserved">this</span>.zoomByFactor(<span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].zoomToScale(scale));
};

kaMap.<span class="reserved">prototype</span>.zoomByFactor = <span class="reserved">function</span>( nZoomFactor ) {
    <span class="reserved">if</span> (nZoomFactor == 1) {
        <span class="reserved">this</span>.triggerEvent( KAMAP_NOTICE, <span class="literal">"NOTICE: changing to current scale aborted"</span>);
        <span class="reserved">return</span>;
    }

    <span class="reserved">this</span>.cellSize = <span class="reserved">this</span>.cellSize/nZoomFactor;
    <span class="reserved">this</span>.setMapLayers();
    <span class="reserved">this</span>.initializeLayers(nZoomFactor);

    <span class="reserved">this</span>.triggerEvent( KAMAP_SCALE_CHANGED, <span class="reserved">this</span>.getCurrentScale() );
    <span class="reserved">this</span>.triggerEvent( KAMAP_EXTENTS_CHANGED, <span class="reserved">this</span>.getGeoExtents() );
};

kaMap.<span class="reserved">prototype</span>.getCurrentScale = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].aScales[<span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].currentScale];
};

kaMap.<span class="reserved">prototype</span>.setLayerQueryable = <span class="reserved">function</span>( name, bQueryable ) {
    <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].setLayerQueryable( name, bQueryable );
};

kaMap.<span class="reserved">prototype</span>.setLayerVisibility = <span class="reserved">function</span>( name, bVisible ) {
    <span class="reserved">if</span>(!<span class="reserved">this</span>.loadUnchecked &amp;&amp; bVisible) {
        layer=<span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].getLayer(name);
        layer.visible=true;
        <span class="reserved">this</span>.setMapLayers();
        <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].setLayerVisibility( name, bVisible );
        <span class="reserved">this</span>.paintLayer(layer);
    } <span class="reserved">else</span> {
        <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].setLayerVisibility( name, bVisible );
    }
};

kaMap.<span class="reserved">prototype</span>.setLayerOpacity = <span class="reserved">function</span>( name, opacity ) {
    <span class="reserved">this</span>.aMaps[<span class="reserved">this</span>.currentMap].setLayerOpacity( name, opacity );
};

kaMap.<span class="reserved">prototype</span>.registerEventID = <span class="reserved">function</span>( eventID ) {
    <span class="reserved">return</span> <span class="reserved">this</span>.eventManager.registerEventID(eventID);
};

kaMap.<span class="reserved">prototype</span>.registerForEvent = <span class="reserved">function</span>( eventID, obj, func ) {
    <span class="reserved">return</span> <span class="reserved">this</span>.eventManager.registerForEvent(eventID, obj, func);
};

kaMap.<span class="reserved">prototype</span>.deregisterForEvent = <span class="reserved">function</span>( eventID, obj, func ) {
    <span class="reserved">return</span> <span class="reserved">this</span>.eventManager.deregisterForEvent(eventID, obj, func);
};

kaMap.<span class="reserved">prototype</span>.triggerEvent = <span class="reserved">function</span>( eventID <span class="comment">/*pass additional arguments*/</span> ) {
    <span class="reserved">return</span> <span class="reserved">this</span>.eventManager.triggerEvent.apply( <span class="reserved">this</span>.eventManager, arguments );
};

<span class="comment">/**
 * special helper function to parse an integer value safely in case
 * it is represented in IEEE format (scientific notation).
 */</span>
<span class="reserved">function</span> safeParseInt( val ) {
    <span class="reserved">return</span> Math.round(parseFloat(val));
};

<span class="comment">/******************************************************************************
 * _map
 *
 * internal class used to store map objects coming from the init script
 *
 * szName - string, the layer name (or group name, in this case ;))
 *
 * szTitle - string, the human-readable title of the map
 *
 * nCurrentScale - integer, the current scale as an index into aszScales;
 *
 * aszScales - array, an array of scale values for zooming.  The first scale is
 *             assumed to be the default scale of the map
 *
 * aszLayers - array, an array of layer names and statuses.  The array is indexed by
 *             the layer name and the value is true or false for the status.
 *
 *****************************************************************************/</span>
<span class="reserved">function</span> _map(o) {
    <span class="reserved">this</span>.aLayers = [];
    <span class="reserved">this</span>.aZoomTo = [];
    <span class="reserved">this</span>.kaMap = null;
    <span class="reserved">this</span>.name = (typeof(o.name) != <span class="literal">'undefined'</span>) ? o.name : <span class="literal">'noname'</span>;
    <span class="reserved">this</span>.title = (typeof(o.title) != <span class="literal">'undefined'</span>) ? o.title : <span class="literal">'no title'</span>;
    <span class="reserved">this</span>.aScales = (typeof(o.scales) != <span class="literal">'undefined'</span>) ? o.scales : [1];
    <span class="reserved">this</span>.currentScale = (typeof(o.currentScale) != <span class="literal">'undefined'</span>) ? parseFloat(o.currentScale) : 0;
    <span class="reserved">this</span>.units = (typeof(o.units) != <span class="literal">'undefined'</span>) ? o.units : 5;
    <span class="reserved">this</span>.resolution = (typeof(o.resolution) != <span class="literal">'undefined'</span>) ? o.resolution:72; <span class="comment">//used in scale calculations</span>
    <span class="reserved">this</span>.defaultExtents = (typeof(o.defaultExtents) != <span class="literal">'undefined'</span>) ? o.defaultExtents:[];
    <span class="reserved">this</span>.currentExtents = (typeof(o.currentExtents) != <span class="literal">'undefined'</span>) ? o.currentExtents:[];
    <span class="reserved">this</span>.maxExtents = (typeof(o.maxExtents) != <span class="literal">'undefined'</span>) ? o.maxExtents : [];
    <span class="reserved">this</span>.backgroundColor = (typeof(o.backgroundColor) != <span class="literal">'undefined'</span>) ? o.backgroundColor : <span class="literal">'#ffffff'</span>;
    <span class="comment">//to be used for versioning the map file ...</span>
    <span class="reserved">this</span>.version = (typeof(o.version) != <span class="literal">'undefined'</span>) ? o.version : <span class="literal">"0"</span>;
};

_map.<span class="reserved">prototype</span>.addLayer = <span class="reserved">function</span>( layer ) {
    layer._map = <span class="reserved">this</span>;
    layer.zIndex = <span class="reserved">this</span>.aLayers.length;
    <span class="reserved">this</span>.aLayers.push( layer );
};

<span class="comment">//added by cappu</span>
_map.<span class="reserved">prototype</span>.removeLayer = <span class="reserved">function</span>( l ) {
  var alayer=Array();
  <span class="reserved">for</span>(i=0,a=0;i&lt;<span class="reserved">this</span>.aLayers.length;i++) {
      <span class="reserved">if</span>(<span class="reserved">this</span>.aLayers[i]!=l) {
          alayer[a]=<span class="reserved">this</span>.aLayers[i];
          a++;
      }
  }
  <span class="reserved">this</span>.aLayers=alayer;
  <span class="reserved">return</span> true;
};

<span class="comment">//modified by cappu return only layer querable and visible for current scale</span>
_map.<span class="reserved">prototype</span>.getQueryableLayers = <span class="reserved">function</span>() {
    var r = [];
    var l = <span class="reserved">this</span>.getLayers();
    <span class="reserved">for</span>( var i=0; i&lt;l.length; i++) {
        <span class="reserved">if</span> (l[i].isQueryable()) {
            r.push(l[i]);
        }
    }
    <span class="reserved">return</span> r;
};

<span class="comment">//modified by cappu, return only layer visible and checked for current scale !!</span>
_map.<span class="reserved">prototype</span>.getLayers = <span class="reserved">function</span>() {
    var r = [];
    <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.aLayers.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aLayers[i].isVisible() &amp;&amp;
            (<span class="reserved">this</span>.aLayers[i].visible || <span class="reserved">this</span>.kaMap.loadUnchecked) ) {
            r.push(<span class="reserved">this</span>.aLayers[i]);
        }
    }
    <span class="reserved">return</span> r;
};

<span class="comment">//added by cappu replace old getQueryableLayers</span>
_map.<span class="reserved">prototype</span>.getAllQueryableLayers = <span class="reserved">function</span>() {
    var r = [];
    <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.aLayers.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aLayers[i].isQueryable()) {
            r.push(<span class="reserved">this</span>.aLayers[i]);
        }
    }
    <span class="reserved">return</span> r;
};

<span class="comment">//added by cappu replace old getLayers</span>
_map.<span class="reserved">prototype</span>.getAllLayers = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.aLayers;
};

_map.<span class="reserved">prototype</span>.getLayer = <span class="reserved">function</span>( name ) {
    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.aLayers.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aLayers[i].name == name) {
            <span class="reserved">return</span> <span class="reserved">this</span>.aLayers[i];
        }
    }
};

_map.<span class="reserved">prototype</span>.getScales = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.aScales;
};

_map.<span class="reserved">prototype</span>.zoomIn = <span class="reserved">function</span>() {
    var nZoomFactor = 1;
    <span class="reserved">if</span> (<span class="reserved">this</span>.currentScale &lt; <span class="reserved">this</span>.aScales.length - 1) {
        nZoomFactor = <span class="reserved">this</span>.aScales[<span class="reserved">this</span>.currentScale]/<span class="reserved">this</span>.aScales[<span class="reserved">this</span>.currentScale+1];
        <span class="reserved">this</span>.currentScale = <span class="reserved">this</span>.currentScale + 1;
    }
    <span class="reserved">return</span> nZoomFactor;
};

_map.<span class="reserved">prototype</span>.zoomOut = <span class="reserved">function</span>() {
    var nZoomFactor = 1;
    <span class="reserved">if</span> (<span class="reserved">this</span>.currentScale &gt; 0) {
        nZoomFactor = <span class="reserved">this</span>.aScales[<span class="reserved">this</span>.currentScale]/<span class="reserved">this</span>.aScales[<span class="reserved">this</span>.currentScale-1];
        <span class="reserved">this</span>.currentScale = <span class="reserved">this</span>.currentScale - 1;
    }
    <span class="reserved">return</span> nZoomFactor;
};

_map.<span class="reserved">prototype</span>.zoomToScale = <span class="reserved">function</span>( scale ) {
    var nZoomFactor = 1;
    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.aScales.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.aScales[i] == scale) {
            nZoomFactor = <span class="reserved">this</span>.aScales[<span class="reserved">this</span>.currentScale]/scale;
            <span class="reserved">this</span>.currentScale = parseInt(i);
        }
    }
    <span class="reserved">return</span> nZoomFactor;
};

_map.<span class="reserved">prototype</span>.setLayerQueryable = <span class="reserved">function</span>( name, bQueryable ) {
    var layer = <span class="reserved">this</span>.getLayer( name );
    layer.setQueryable( bQueryable );
};

_map.<span class="reserved">prototype</span>.setLayerVisibility = <span class="reserved">function</span>( name, bVisible ) {
    var layer = <span class="reserved">this</span>.getLayer( name );
    layer.setVisibility( bVisible );
};

_map.<span class="reserved">prototype</span>.setLayerOpacity = <span class="reserved">function</span>( name, opacity ) {
    var layer = <span class="reserved">this</span>.getLayer( name );
    layer.setOpacity( opacity );
};

_map.<span class="reserved">prototype</span>.setDefaultExtents = <span class="reserved">function</span>( minx, miny, maxx, maxy ){
    <span class="reserved">this</span>.defaultExtents = [minx, miny, maxx, maxy];
    <span class="reserved">if</span> (<span class="reserved">this</span>.currentExtents.length == 0)
        <span class="reserved">this</span>.setCurrentExtents( minx, miny, maxx, maxy );
};

_map.<span class="reserved">prototype</span>.setCurrentExtents = <span class="reserved">function</span>( minx, miny, maxx, maxy ) {
    <span class="reserved">this</span>.currentExtents = [minx, miny, maxx, maxy];
};

_map.<span class="reserved">prototype</span>.setMaxExtents = <span class="reserved">function</span>( minx, miny, maxx, maxy ) {
    <span class="reserved">this</span>.maxExtents = [minx, miny, maxx, maxy];
};

_map.<span class="reserved">prototype</span>.setBackgroundColor = <span class="reserved">function</span>( szBgColor ) {
    <span class="reserved">this</span>.backgroundColor = szBgColor;
};

<span class="comment">/******************************************************************************
 * _layer
 *
 * internal class used to store map layers within a map.  Map layers track
 * visibility of the layer in the user interface.  Parameters are passed
 * as an object with the following attributes:
 *
 * name - string, the name of the layer
 * visible - boolean, the current state of the layer (true is visible)
 * opacity - integer, between 0 (transparent) and 100 (opaque), controls opacity
 *           of the layer as a whole
 * imageformat - string, the format to request the tiles in for this layer.  Can
 *               be used to optimize file sizes for different layer types
 *               by using GIF for images with fewer colours and JPEG or PNG24
 *               for high-colour layers (such as raster imagery).
 *
 * queryable - boolean, is the layer queryable?  This is different from the
 *              layer being included in queries.  bQueryable marks a layer as
 *              being capable of being queried.  The layer also has to have
 *              it's query state turned on using setQueryable
 * scales     - array to containing the layer visibility for each scale
 * force    - force layer
 *****************************************************************************/</span>
<span class="reserved">function</span> _layer( o ) {
    <span class="reserved">this</span>.domObj = null;
    <span class="reserved">this</span>._map = null;
    <span class="reserved">this</span>.name = (typeof(o.name) != <span class="literal">'undefined'</span>) ? o.name : <span class="literal">'unnamed'</span>;
    <span class="reserved">this</span>.visible = (typeof(o.visible) != <span class="literal">'undefined'</span>) ? o.visible : true;
    <span class="reserved">this</span>.opacity = (typeof(o.opacity) != <span class="literal">'undefined'</span>) ? o.opacity : 100;
    <span class="reserved">this</span>.imageformat = (typeof(o.imageformat) != <span class="literal">'undefined'</span>) ? o.imageformat : null;
    <span class="reserved">this</span>.queryable = (typeof(o.queryable) != <span class="literal">'undefined'</span>) ? o.queryable : false;
    <span class="reserved">this</span>.queryState = (typeof(o.queryable) != <span class="literal">'undefined'</span>) ? o.queryable : false;
    <span class="reserved">this</span>.tileSource = (typeof(o.tileSource) != <span class="literal">'undefined'</span>) ? o.tileSource : <span class="literal">'auto'</span>;
    <span class="reserved">this</span>.scales = (typeof(o.scales) != <span class="literal">'undefined'</span>) ? o.scales : new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
    <span class="reserved">this</span>.toLoad=0;
};

_layer.<span class="reserved">prototype</span>.isQueryable = <span class="reserved">function</span>() {
    <span class="reserved">return</span> <span class="reserved">this</span>.queryState;
};

_layer.<span class="reserved">prototype</span>.setQueryable = <span class="reserved">function</span>( bQueryable ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.queryable) {
        <span class="reserved">this</span>.queryState = bQueryable;
    }
};

<span class="comment">//added by  cappu check layer visibility at current scale</span>
_layer.<span class="reserved">prototype</span>.isVisible= <span class="reserved">function</span>() {
    <span class="reserved">return</span> (<span class="reserved">this</span>.scales[<span class="reserved">this</span>._map.currentScale]==1)? true:false;
};

<span class="comment">/**
 * layer.setOpacity( amount )
 *
 * set a layer to be semi transparent.  Amount is a number between
 * 0 and 100 where 0 is fully transparent and 100 is fully opaque
 */</span>
_layer.<span class="reserved">prototype</span>.setOpacity = <span class="reserved">function</span>( amount ) {
    <span class="reserved">this</span>.opacity = amount;
    <span class="reserved">if</span> (<span class="reserved">this</span>.domObj) {
        <span class="reserved">this</span>.domObj.style.opacity = amount/100;
        <span class="reserved">this</span>.domObj.style.mozOpacity = amount/100;
        <span class="reserved">for</span>(var i=0;i&lt;<span class="reserved">this</span>.domObj.childNodes.length;i++) {
            <span class="reserved">this</span>.domObj.childNodes[i].style.filter = <span class="literal">"Alpha(opacity="</span>+amount+<span class="literal">")"</span>;
        }
    }
};

_layer.<span class="reserved">prototype</span>.setTile = <span class="reserved">function</span>(img) {
    var l = safeParseInt(img.style.left) + <span class="reserved">this</span>._map.kaMap.xOrigin;
    var t = safeParseInt(img.style.top) + <span class="reserved">this</span>._map.kaMap.yOrigin;
    <span class="comment">// dynamic imageformat</span>
    var szImageformat = <span class="literal">''</span>;
    var image_format = <span class="literal">''</span>;
    <span class="reserved">if</span> (<span class="reserved">this</span>.imageformat &amp;&amp; <span class="reserved">this</span>.imageformat != <span class="literal">''</span>) {
        image_format = <span class="reserved">this</span>.imageformat;
        szImageformat = <span class="literal">'&amp;i='</span>+image_format;
    }
    <span class="reserved">if</span>(<span class="reserved">this</span>.tileSource == <span class="literal">'cache'</span>) {
        var metaLeft = Math.floor(l/(<span class="reserved">this</span>._map.kaMap.tileWidth * <span class="reserved">this</span>._map.kaMap.metaWidth)) * <span class="reserved">this</span>._map.kaMap.tileWidth * <span class="reserved">this</span>._map.kaMap.metaWidth;
        var metaTop = Math.floor(t/(<span class="reserved">this</span>._map.kaMap.tileHeight * <span class="reserved">this</span>._map.kaMap.metaHeight)) * <span class="reserved">this</span>._map.kaMap.tileHeight * <span class="reserved">this</span>._map.kaMap.metaHeight;
        var metaTileId = <span class="literal">'t'</span> + metaTop + <span class="literal">'l'</span> + metaLeft;
        var groupsDir = (<span class="reserved">this</span>.name != <span class="literal">''</span>) ? <span class="reserved">this</span>.name.replace(/\W/g, <span class="literal">'_'</span>) : <span class="literal">'def'</span>;
        var cacheDir = <span class="reserved">this</span>._map.kaMap.webCache + <span class="reserved">this</span>._map.name + <span class="literal">'/'</span> + <span class="reserved">this</span>._map.aScales[<span class="reserved">this</span>._map.currentScale] + <span class="literal">'/'</span> + groupsDir + <span class="literal">'/def/'</span> + metaTileId;
        var tileId = <span class="literal">"t"</span> + t + <span class="literal">"l"</span> + l;
        <span class="comment">// the following conversion of image format to image extension</span>
        <span class="comment">// works for JPEG, GIF, PNG, PNG24 - others may need different treatment</span>
        var imageExtension = <span class="reserved">this</span>.imageformat.toLowerCase().replace(/[\de]/g, <span class="literal">''</span>);
        var src = cacheDir + <span class="literal">"/"</span> + tileId + <span class="literal">"."</span> + imageExtension;
    } <span class="reserved">else</span> {
        var szForce = <span class="literal">''</span>;
        var szLayers = <span class="literal">''</span>;
        <span class="reserved">if</span> (arguments[1] || <span class="reserved">this</span>.tileSource == <span class="literal">'redraw'</span>) {
            szForce = <span class="literal">'&amp;force=true'</span>;
        }
        var szGroup = <span class="literal">'&amp;g='</span>+img.layer.domObj.id;
        var szScale = <span class="literal">'&amp;s='</span>+<span class="reserved">this</span>._map.aScales[<span class="reserved">this</span>._map.currentScale];
        var src = <span class="reserved">this</span>._map.kaMap.server+
                  <span class="reserved">this</span>._map.kaMap.tileURL+
                  <span class="literal">'?map='</span>+<span class="reserved">this</span>._map.name+
                  <span class="literal">'&amp;t='</span>+t+
                  <span class="literal">'&amp;l='</span>+l+
                  szScale+szForce+szGroup+szImageformat;
    }
    <span class="reserved">if</span> ((<span class="reserved">this</span>.isIE4) &amp;&amp; (image_format.toLowerCase() == <span class="literal">"png24"</span>)) {
        <span class="comment">//apply png24 hack for IE</span>
        img.style.visibility = <span class="literal">'hidden'</span>;
        img.src = <span class="reserved">this</span>._map.kaMap.aPixel.src;
        img.style.filter = <span class="literal">"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"</span>+src+<span class="literal">"', sizingMethod='scale')"</span>;
    } <span class="reserved">else</span> {
        <span class="reserved">if</span> (img.src != src) {
            img.style.visibility = <span class="literal">'hidden'</span>;
            img.src = src;
        }
    }
};

_layer.<span class="reserved">prototype</span>.setVisibility = <span class="reserved">function</span>( bVisible ) {
    <span class="reserved">this</span>.visible = bVisible;
    <span class="reserved">if</span> (<span class="reserved">this</span>.domObj) {
        <span class="reserved">this</span>.domObj.style.visibility = bVisible?<span class="literal">'visible'</span>:<span class="literal">'hidden'</span>;
        <span class="comment">//horrid hack - this is needed in case any element contained</span>
        <span class="comment">//within the div has its visibility set ... it overrides the</span>
        <span class="comment">//style of the container!!!</span>
        <span class="reserved">this</span>.domObj.style.display = bVisible?<span class="literal">'block'</span>:<span class="literal">'none'</span>;
	    <span class="reserved">for</span>( var i=0; i&lt;<span class="reserved">this</span>.domObj.childNodes.length; i++) {
	        <span class="reserved">this</span>.setTile(<span class="reserved">this</span>.domObj.childNodes[i]);
	    }
		<span class="reserved">this</span>._map.kaMap.triggerEvent( KAMAP_LAYER_STATUS_CHANGED, <span class="reserved">this</span> );
	}
};

_layer.<span class="reserved">prototype</span>.setZIndex = <span class="reserved">function</span>( zIndex ) {
    <span class="reserved">this</span>.zIndex = zIndex;
    <span class="reserved">if</span> (<span class="reserved">this</span>.domObj) {
        <span class="reserved">this</span>.domObj.style.zIndex = zIndex;
    }
};

<span class="comment">//Set all layers tile added by cappu</span>
_layer.<span class="reserved">prototype</span>.setTileLayer = <span class="reserved">function</span>() {
    var szForce = <span class="literal">''</span>;
    var szLayers = <span class="literal">''</span>;
    <span class="reserved">this</span>.loaded=0;
    <span class="reserved">if</span> (arguments[0]) {
        szForce = <span class="literal">'&amp;force=true'</span>;
    }

    var szGroup = <span class="literal">"&amp;g="</span>+<span class="reserved">this</span>.name;
    var szScale = <span class="literal">'&amp;s='</span>+<span class="reserved">this</span>._map.aScales[<span class="reserved">this</span>._map.currentScale];

    <span class="comment">// dynamic imageformat</span>
    var szImageformat = <span class="literal">''</span>;
    var image_format = <span class="literal">''</span>;
    <span class="reserved">if</span> (<span class="reserved">this</span>.imageformat &amp;&amp; <span class="reserved">this</span>.imageformat != <span class="literal">''</span>) {
        image_format = <span class="reserved">this</span>.imageformat;
        szImageformat = <span class="literal">'&amp;i='</span>+image_format;
    }
    <span class="reserved">for</span>(i=0;i&lt;<span class="reserved">this</span>.domObj.childNodes.length;i++) {
        img=<span class="reserved">this</span>.domObj.childNodes[i];
        var l = safeParseInt(img.style.left) + <span class="reserved">this</span>._map.kaMap.xOrigin;
        var t = safeParseInt(img.style.top) + <span class="reserved">this</span>._map.kaMap.yOrigin;
        var src = <span class="reserved">this</span>._map.kaMap.server+
              <span class="reserved">this</span>._map.kaMap.tileURL+
              <span class="literal">'?map='</span>+<span class="reserved">this</span>._map.name+
              <span class="literal">'&amp;t='</span>+t+
              <span class="literal">'&amp;l='</span>+l+
              szScale+szForce+szGroup+szImageformat;
        <span class="comment">//che tipo di hack modificatre non funziona il controllo che c'è sotto</span>
        <span class="reserved">if</span> ((<span class="reserved">this</span>.isIE4) &amp;&amp; (image_format.toLowerCase() == <span class="literal">"png24"</span>)) {
            <span class="comment">//apply png24 hack for IE</span>
            img.style.visibility = <span class="literal">'hidden'</span>;
            img.src = <span class="reserved">this</span>._map.kaMap.aPixel.src;
            img.style.filter = <span class="literal">"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"</span>+src+<span class="literal">"', sizingMethod='scale')"</span>;
        } <span class="reserved">else</span> {
            <span class="reserved">if</span> (img.src != src) {
                img.style.visibility = <span class="literal">'hidden'</span>;
                img.src = src;
            }
        }
    }
};

<span class="comment">/******************************************************************************
 * Event Manager class
 *
 * an internal class for managing generic events.  kaMap! uses the event
 * manager internally and exposes certain events to the application.
 *
 * the kaMap class provides wrapper functions that hide this implementation
 * useage:
 *
 * myKaMap.registerForEvent( gnSomeEventID, myObject, myFunction );
 * myKaMap.registerForEvent( 'SOME_EVENT', myObject, myFunction );
 *
 * myKaMap.deregisterForEvent( gnSomeEventID, myObject, myFunction );
 * myKaMap.deregisterForEvent( 'SOME_EVENT', myObject, myFunction );
 *
 * myObject is normally null but can be a javascript object to have myFunction
 * executed within the context of an object (becomes 'this' in the function).
 *
 *****************************************************************************/</span>
<span class="reserved">function</span> _eventManager( )
{
    <span class="reserved">this</span>.events = [];
    <span class="reserved">this</span>.lastEventID = 0;
}

_eventManager.<span class="reserved">prototype</span>.registerEventID = <span class="reserved">function</span>( eventID ) {
    var ev = new String(eventID);
    <span class="reserved">if</span> (!<span class="reserved">this</span>.events[eventID]) {
        <span class="reserved">this</span>.events[eventID] = [];
    }
};

_eventManager.<span class="reserved">prototype</span>.registerForEvent = <span class="reserved">function</span>(eventID, obj, func) {
    var ev = new String(eventID);
    <span class="reserved">this</span>.events[eventID].push( [obj, func] );
};

_eventManager.<span class="reserved">prototype</span>.deregisterForEvent = <span class="reserved">function</span>( eventID, obj, func ) {
    var ev = new String(eventID);
    var bResult = false;
    <span class="reserved">if</span> (!<span class="reserved">this</span>.events[eventID]) {
        <span class="reserved">return</span> false;
    }

    <span class="reserved">for</span> (var i=0;i&lt;<span class="reserved">this</span>.events[eventID].length;i++) {

        <span class="reserved">if</span> (<span class="reserved">this</span>.events[eventID][i][0] == obj &amp;&amp;
            <span class="reserved">this</span>.events[eventID][i][1] == func) {
            <span class="reserved">this</span>.events[eventID].splice(i,1);
            bResult = true;
        }
    }
    <span class="reserved">return</span> bResult;
};

_eventManager.<span class="reserved">prototype</span>.triggerEvent = <span class="reserved">function</span>( eventID ) {
    var ev = new String(eventID);
    <span class="reserved">if</span> (!<span class="reserved">this</span>.events[eventID]) {
        <span class="reserved">return</span> false;
    }

    var args = new Array();
    <span class="reserved">for</span>(i=1; i&lt;arguments.length; i++) {
        args[args.length] = arguments[i];
    }

    <span class="reserved">for</span> (var i=0; i&lt;<span class="reserved">this</span>.events[eventID].length; i++) {
        <span class="reserved">this</span>.events[eventID][i][1].apply( <span class="reserved">this</span>.events[eventID][i][0],
                                          arguments );
    }
    <span class="reserved">return</span> true;
};

<span class="comment">/******************************************************************************
 * Queue Manager class
 *
 * an internal class for managing delayed execution of code.  This uses the
 * window.setTimeout interface but adds support for execution of functions
 * on objects
 *
 * The problem with setTimeout is that you need a reference to a global object
 * to do something useful in an object-oriented environment, and we don't
 * really have that here.  So the Queue Manager handles a stack of pending
 * delayed execution code and evaluates it when it comes due.  It can be
 * used exactly like window.setTimeout in that it returns an id that can
 * subsequently be used to clear the delayed code.
 *
 * To add something to the queue, call
 * var id = goQueueManager.enqueue( timeout, obj, func, args );
 *
 * timeout - time to delay (milliseconds)
 * obj - the object to execute the function within.  Can be null for global
 *       scope
 * func - the function to execute.  Note this is the function, not a string
 *        containing the function.
 * args - an array of values to be passed to the function.
 *
 * To remove a function from the queue, call goQueueManager.dequeue( id );
 *****************************************************************************/</span>
var goQueueManager = new _queueManager();

<span class="reserved">function</span> _queueManager() {
    <span class="reserved">this</span>.queue = new Array();
}

_queueManager.<span class="reserved">prototype</span>.enqueue = <span class="reserved">function</span>( timeout, obj, func, args ) {
    var pos = <span class="reserved">this</span>.queue.length;
    <span class="reserved">for</span> (var i=0; i&lt; <span class="reserved">this</span>.queue.length; i++) {
        <span class="reserved">if</span> (<span class="reserved">this</span>.queue[i] == null) {
            pos = i;
            break;
        }
    }
    var id = window.setTimeout( <span class="literal">"_queueManager_execute("</span>+pos+<span class="literal">")"</span>, timeout );
    <span class="reserved">this</span>.queue[pos] = new Array( id, obj, func, args );
    <span class="reserved">return</span> pos;
};

_queueManager.<span class="reserved">prototype</span>.dequeue = <span class="reserved">function</span>( pos ) {
    <span class="reserved">if</span> (<span class="reserved">this</span>.queue[pos] != null) {
        window.clearTimeout( <span class="reserved">this</span>.queue[pos][0] );
        <span class="reserved">this</span>.queue[pos] = null;
    }
};

<span class="reserved">function</span> _queueManager_execute( pos) {
    <span class="reserved">if</span> (goQueueManager.queue[pos] != null) {
        var obj = goQueueManager.queue[pos][1];
        var func = goQueueManager.queue[pos][2];
        <span class="reserved">if</span> (goQueueManager.queue[pos][3] != null) {
            func.apply( obj, goQueueManager.queue[pos][3] );
        } <span class="reserved">else</span> {
            func.apply( obj );
        }
        goQueueManager.queue[pos] = null;
    }
};</pre>
	<hr>



<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top"><em>
<b>ka-Map</b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<font size="-1">

</font>
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Wed Mar 15 10:50:59 2006</div>
</body>
</html>
